You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by "Carlo.Allocca" <ca...@open.ac.uk> on 2016/01/28 14:14:04 UTC
How to remove consistently a triple pattern given a SPARQL query?
Dear All,
I am using Jena for my project and I would like to submit the following question: How to remove consistently a triple pattern given a SPARQL query?
EXAMPLE:
For example, considering the query “qString1” and the tp=“?boss ex:isBossOf ?ind .”
I need to remove tp from qString1, obtaining qString1. For “Consistently” I mean that the clause FILTER gets affected (as it contains var that appears in the triple pattern too), therefore it needs to be deleted too.
String qString1 =
" SELECT DISTINCT ?ind ?boss ?g where "
+ "{ "
+ " ?ind rdf:type ex:AssociatedResearcher ."
+ " {?ind rdf:type ?z. } UNION "
+ " {?boss ex:isBossOf ?ind . Filter(?boss=\”rossi\”)} "
+ "}";
String qString2 =
" SELECT DISTINCT ?ind ?boss ?g “
+ “WHERE "
+ "{ "
+ " ?ind rdf:type ex:AssociatedResearcher ."
+ " {?ind rdf:type ?z. } UNION "
+ " {} "
+ "}";
The solution that I am trying to implement is based on a visitor “SQRemoveTripleVisitor extends ElementVisitorBase”.
It is quite straightforward to remove the triple pattern when visit(ElementPathBlock el)
@Override
public void visit(ElementPathBlock el) {
if (el == null) {
throw new IllegalStateException("[SQRemoveTripleVisitor::visit(ElementPathBlock el)] The ElementPathBlock is null!!");
}
ListIterator<TriplePath> it = el.getPattern().iterator();
while (it.hasNext()) {
final TriplePath tp1 = it.next();
if (this.tp != null) {
if (this.tp.matches(tp1.asTriple())) {
it.remove();
}
}
}
}
I could not figure out how to remove the associated FILTER when visit(ElementFilter el) as below.
@Override
public void visit(ElementFilter el) {
//...get the variables of the FILTER expression
Expr filterExp = el.getExpr();//.getVarsMentioned().contains(el);
Set<Var> expVars = filterExp.getVarsMentioned();
//...get the variables of the triple pattern that we want to delete
Set<Var> tpVars = new HashSet();
Node subj = this.tp.getSubject();
if (subj.isVariable()) {
tpVars.add((Var) subj);
}
Node pred = this.tp.getPredicate();
if (pred.isVariable()) {
tpVars.add((Var) pred);
}
Node obj = this.tp.getObject();
if (obj.isVariable()) {
tpVars.add((Var) obj);
}
//...check whether the FILTER expression contains any of the triple pattern’s variable
for(Var var:expVars){
//…if it does then we have to delete the entire FILTER expression
if(tpVars.contains(var)){
System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter el)] I NEED TO REMOVE THE FILTER!!!!!! ");
}
}
}
Please, may I ask for any help or idea on how to remove the filter?
Many Thanks in advance.
Best Regards,
Carlo
-- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
Re: How to remove consistently a triple pattern given a SPARQL query?
Posted by Andy Seaborne <an...@apache.org>.
On 02/02/16 19:29, Paul Houle wrote:
> Carlo, Andy,
>
> I like the Iterator<> interfaces in the Jena framework for getting
> data out, but I make a habit of always putting results in a List or
> Queue or something before putting them back into the same Jena model
> because i get less BS per mile that way in terms of Exceptions and
> other exceptional events.
>
> Does Jena have an official policy on being reenterable in that way?
>
Paul - iterators are "normal". Many do not support .remove
Like any Java iterators - do not modify the underlying data structure
while iterating. CCE will result - or wrong answers.
Either copy to a list, or note work to be done and do after the iterator
is no longer needed. Standard java idioms. List<> is good if you can
afford the space.
Beware that ArrayList<> has peculiar growth characteristics for large sizes.
See Iter - like Java8 Stream but for iterators.
Andy
Re: How to remove consistently a triple pattern given a SPARQL query?
Posted by Andy Seaborne <an...@apache.org>.
On 15/02/16 11:12, Carlo.Allocca wrote:
> Hi Lorenz,
>
> Sorry for this. I tried to use colours to highlight the differences. I left in green my original message, in red Andy answer, and in blue my last reply.
>
It comes through as a
Content-Type: multipart/alternative;
boundary="_000_E70178CD020E4CE4B8522E8E9D4AEF5Eopenmailopenacuk_"
with a single part:
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64
Plain text.
Andy
> Hope this helps.
> Many Thanks,
> Carlo
>
> Dear Andy,
>
> Thanks again for your suggesting.
> Some comments in line.
>
> On 13 Feb 2016, at 17:04, Andy Seaborne <an...@apache.org>> wrote:
>
> On 04/02/16 19:27, Carlo.Allocca wrote:
> Dear Andy and All,
>
> Thank you very much for all your suggestions and willingness.
>
> I went through all of them again and, assembling them (changing a bit the code reported in the previous email)
> I got a reasonable first version that is working. But I had to use arg0 instead of arg1 as suggested.
>
> This will get you into trouble!
>
> It probably means something somewhere below is modifying the input structure, not taking a copy.
> I will double check and come back to this.
>
>
>
> Please, could I ask the followings:
>
> Is there any way to access the aggregate expressions (e.g. GROUP BY or HAVING ) when applying an implementation of ElementTransform?
>
> Look at QueryTransformOps.transform(Query query, ..) which applies transaforms to the thigns that attach to the query object itseld like GROUP.
>
> Thanks. I will try this one and see how to combine with the transform that I have implemented.
>
> Many Thanks,
> Best Regards,
> Carlo
>
>
> On 15 Feb 2016, at 11:01, Lorenz Bühmann <bu...@informatik.uni-leipzig.de>> wrote:
>
> Impossible to read as nobody can distinguish between old content and new comments. By the way, the thread is much too long from my point of view
>
> Dear Andy,
>
> Thanks again for your suggesting.
> Some comments in line.
>
> On 13 Feb 2016, at 17:04, Andy Seaborne <an...@apache.org>> wrote:
>
> On 04/02/16 19:27, Carlo.Allocca wrote:
> Dear Andy and All,
>
> Thank you very much for all your suggestions and willingness.
>
> I went through all of them again and, assembling them (changing a bit the code reported in the previous email)
> I got a reasonable first version that is working. But I had to use arg0 instead of arg1 as suggested.
>
> This will get you into trouble!
>
> It probably means something somewhere below is modifying the input structure, not taking a copy.
> I will double check and come back to this.
>
>
>
> Please, could I ask the followings:
>
> Is there any way to access the aggregate expressions (e.g. GROUP BY or HAVING ) when applying an implementation of ElementTransform?
>
> Look at QueryTransformOps.transform(Query query, ..) which applies transaforms to the thigns that attach to the query object itseld like GROUP.
>
> Thanks. I will try this one and see how to combine with the transform that I have implemented.
>
> Many Thanks,
> Best Regards,
> Carlo
>
>
> The reason of such a question is: when applying the operation remove of the triple (?x2 foaf:mbox2 ?mbox2 .) over Q1,
> it would make sense to eliminate ORDER BY too as it contains a variable (?x2) from the triple that was eliminated and there no other triple containing such a variable.
>
> Q1:
>
> String qString8 =
> SELECT DISTINCT ?x2 ?mbox2 where "
> {
> ?x foaf:name ?name .
> ?x2 foaf:mbox2 ?mbox2 .
> }
> ORDER BY ?x2
>
>
> Many Thanks in advance.
> Best Regards,
> Carlo
>
>
>
>
> On 3 Feb 2016, at 14:55, Carlo.Allocca <ca...@open.ac.uk>> wrote:
>
> Dear Andy and All,
>
> sorry for this long thread.
> I am sure I was not able to put in practice some of your suggestions.
>
> I put the full code here http://collabedit.com/wfhtq and reported below.
>
> I tested it over the Q1 with the triple (?boss ex:isBossOf ?ind).
>
> =========== BEFORE Q1:
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
>
>
>
> ============= AFTER Q1:
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { # Empty BGP
>
> FILTER ( ?boss = "mathieu" )
> }
> }
>
>
> But the filter is still there even if when I trace the execution it removes it.
> I am doing the update between the AST and remove of the filter in
>
> @Override
> public Element transform(ElementGroup arg0, List<Element> arg1) {
> Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
> Element elem = itr.next();
> …
> ...
> }
>
> //With this code I am saying the following: make effective all the modifications that //have been made so far, if any.
> if (arg0.getElements() == arg1)
> { return arg0; }
> else {
> ElementGroup el2 = new ElementGroup();
> el2.getElements().addAll(arg1);
> return el2;
> }
>
> }
>
>
> What am I doing wrong?
>
> Many Thanks for your help.
>
> Best Regards,
> Carlo
>
>
>
>
>
> === Code
>
> //The main Class
>
> public class RemoveTriple {
>
> public RemoveTriple(){
> super();
> }
>
> public Query removeTP(Query q, Triple tp) {
> RemoveOpTransform rOpTransform = new RemoveOpTransform(q,tp);
> Query queryWithoutTriplePattern = QueryTransformOps.transform(q, rOpTransform) ;
> return queryWithoutTriplePattern;
> }
> }
>
> // The current implementation of the RemoveOpTransform class. The class that implements the removal of the triple
>
> public class RemoveOpTransform implements ElementTransform {
>
> private Query query;
> private Triple triple;
>
> public RemoveOpTransform(Query q, Triple tp) {
> this.query = q;
> this.triple = tp;
> }
>
> @Override
> public Element transform(ElementTriplesBlock arg0) {
> System.out.println("[RemoveOpTransform::transform(ElementTriplesBlock arg0)] " + arg0.toString());
> System.out.println("");
> return arg0;
> }
>
> // This is the code related to the
> @Override
> public Element transform(ElementPathBlock eltPB) {
> if (eltPB.isEmpty()) {
> return eltPB;
> }
> Iterator<TriplePath> l = eltPB.patternElts();
> while (l.hasNext()) {
> TriplePath tp = l.next();
> if (tp.asTriple().matches(this.triple)) {
> l.remove();
> return this.transform(eltPB);//eltPB;
> }
> }
> return eltPB;
> }
>
>
> @Override
> public Element transform(ElementGroup arg0, List<Element> arg1) {
>
> Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
> Element elem = itr.next();
> // I should go one by one the and examinate all the possible cases. For example:
>
> //UNNION
> if (elem instanceof ElementUnion) {
> if (isUnionBothSidesEmpty) {
> itr.remove();
> }
> }
>
> //OPTION
> if (elem instanceof ElementOptional) {
> boolean isElementOptionalEmpty = isElementOptionalEmpty((ElementOptional) elem);
> if (isElementOptionalEmpty) {
> itr.remove();
> // ElementGroup el2 = new ElementGroup();
> // el2.getElements().addAll(arg1);
> // return el2;
> }
> }
>
> //ELEMENTGROUP
> if (elem instanceof ElementGroup) {
> boolean isElementGroupEmpty = isElementGroupEmpty((ElementGroup) elem);
> if (isElementGroupEmpty) {
> itr.remove();
> // ElementGroup el2 = new ElementGroup();
> // el2.getElements().addAll(arg1);
> // return el2;
> }
> }
>
> //FILTER
> if (elem instanceof ElementFilter) {
> //... check if this filter is the one that we should remove
> //...get the variables of the triple pattern that we want to delete
> Set<Var> tpVars = new HashSet();
> Node subj = this.triple.getSubject();
> if (subj.isVariable()) {
> tpVars.add((Var) subj);
> }
> Node pred = this.triple.getPredicate();
> if (pred.isVariable()) {
> tpVars.add((Var) pred);
> }
> Node obj = this.triple.getObject();
> if (obj.isVariable()) {
> tpVars.add((Var) obj);
> }
> //...get the variables of the FILTER expression
> Set<Var> expVars = ((ElementFilter) elem).getExpr().getVarsMentioned();
> //...check whether the FILTER expression contains any of the triple pattern variable
> for (Var var : expVars) {
> //...if it does then we can delete the entire FILTER expression
> if (tpVars.contains(var)) {
> itr.remove();
> break;
> }
> }
> }
>
> }// End of While
>
> //With this code I am saying the following: make effective all the modifications that
> //have been made so far, if any.
> if (arg0.getElements() == arg1) {
> return arg0;
> } else {
> ElementGroup el2 = new ElementGroup();
> el2.getElements().addAll(arg1);
> return el2;
> }
> }
>
>
>
>
> @Override
> public Element transform(ElementFilter arg0, Expr arg1) {
> return arg0;
> }
>
> @Override
> public Element transform(ElementAssign arg0, Var arg1, Expr arg2) {
> return arg0;
> }
>
> @Override
> public Element transform(ElementBind arg0, Var arg1, Expr arg2) {
> System.out.println("[RemoveOpTransform::transform(ElementBind arg0)] " + arg0.toString());
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementData arg0) {
> System.out.println("[RemoveOpTransform::transform(ElementData arg0)] " + arg0.toString());
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementDataset arg0, Element arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementDataset arg0)] " + arg0.toString());
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementUnion arg0, List<Element> arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementUnion arg0)] arg0 " + arg0.toString());
> System.out.println("[RemoveOpTransform::transform(ElementUnion arg0)] arg1 " + arg1.toString());
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementOptional arg0, Element arg1) {
> return arg0;
> }
>
> @Override
> public Element transform(ElementNamedGraph arg0, Node arg1, Element arg2) {
> System.out.println("[RemoveOpTransform::transform(ElementNamedGraph arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementExists arg0, Element arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementExists arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementNotExists arg0, Element arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementNotExists arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementMinus arg0, Element arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementMinus arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementService arg0, Node arg1, Element arg2) {
> System.out.println("[RemoveOpTransform::transform(ElementService arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementSubQuery arg0, Query arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementSubQuery arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> private boolean isUnionBothSidesEmpty1(ElementUnion elementUnion) {
> List<Element> elemListUnion = elementUnion.getElements();//.getElements();
> if (elemListUnion.size() == 2) {
> Element left = elemListUnion.get(0);
> Element right = elemListUnion.get(1);
> if (left instanceof ElementGroup && right instanceof ElementGroup) {
> if ((((ElementGroup) left).getElements().size() == 1) && (((ElementGroup) right).getElements().size() == 1)) {
> Element elLeft = ((ElementGroup) left).getElements().get(0);
> Element elRight = ((ElementGroup) right).getElements().get(0);
> if ((elLeft instanceof ElementPathBlock) && (elRight instanceof ElementPathBlock)) {
> ElementPathBlock epbLeft = (ElementPathBlock) elLeft;
> ElementPathBlock epbRight = (ElementPathBlock) elRight;
> if (epbLeft.isEmpty() && epbRight.isEmpty()) {
> return true;
> }
> }
> }
> }
> }
> return false;
> }
>
> private boolean isElementGroupEmpty(ElementGroup elementGroup) {
> List<Element> elList = ((ElementGroup) elementGroup).getElements();
> if (elList.size() == 1) {
> Element el = (Element) elList.get(0);
> if (el instanceof ElementPathBlock) {
> ElementPathBlock tmp = (ElementPathBlock) el;
> if (tmp.isEmpty()) {
> return true;
> }
> }
> }
> return false;
> }
>
> private boolean isElementOptionalEmpty(ElementOptional elementOptional) {
> Element elm = ((ElementOptional) elementOptional).getOptionalElement();//.getElements();
> if (elm instanceof ElementGroup) {
> List<Element> elList = ((ElementGroup) elm).getElements();
> if (elList.size() == 1) {
> Element el = (Element) elList.get(0);
> if (el instanceof ElementPathBlock) {
> ElementPathBlock tmp = (ElementPathBlock) el;
> if (tmp.isEmpty()) {
> return true;
> }
> }
> }
> }
> return false;
> }
>
> }
>
>
>
>
>
>
>
>
> On 3 Feb 2016, at 00:00, Carlo.Allocca <ca...@open.ac.uk>> wrote:
>
> Dear Andy and Paul,
>
> some comments follow in lines.
>
> On 2 Feb 2016, at 22:33, Andy Seaborne <an...@apache.org>> wrote:
>
> On 02/02/16 19:29, Paul Houle wrote:
> Carlo, Andy,
>
> I like the Iterator<> interfaces in the Jena framework for getting data
> out, but I make a habit of always putting results in a List or Queue or
> something before putting them back into the same Jena model because i get
> less BS per mile that way in terms of Exceptions and other exceptional
> events.
>
> Does Jena have an official policy on being reenterable in that way?
>
> Carlo's issues are nothing to do with iterator policy.
>
> Carlo - Use arg1 else you will not see your changes so far.
>
> In
>
> public Element transform(ElementGroup arg0, List<Element> arg1)
>
> arg0 is the element from the AST before modification and
> arg1 is the new elements to go in after modification by lower levels of the bottom-up rewrite.
>
>
> So if you rewrite a ElementFilter by making a new one, it will appear in arg1 not in arg0.
> I see. Thank you. Based on this, I am going to use "Iterator<Element> itr = arg1.iterator(); when implementing
> public Element transform(ElementGroup arg0, List<Element> arg1).
>
>
>
> Do not modify the Element* arguments in place.
>
>
> See ElementTransformCopyBase
>
> The default implementation is:
>
> @Override
> public Element transform(ElementGroup el, List<Element> elts) {
> if ( el.getElements() == elts )
> return el ;
> ElementGroup el2 = new ElementGroup() ;
> el2.getElements().addAll(elts) ;
> return el2 ;
> }
>
>
> i.e if any change, detected by being not the exact identical list, then do a copy of the structure. This saves object churn.
>
> I am going to change my implementation in such a way include all the above suggestions and clarifications.
>
> Many Thanks for your willingness.
> Best Regards,
> Carlo.
>
>
> Andy
>
>
> On Tue, Feb 2, 2016 at 2:13 PM, Carlo.Allocca <ca...@open.ac.uk>>
> wrote:
>
>
> Dear Andy and All,
>
> while I was extending and testing the code that I wrote so far concerning
> the removing a triple from a given SPARQL query,
> I realised that I get different outputs depending on how I start the
> implementation of the public Element transform(ElementGroup arg0,
> List<Element> arg1).
> In particular, if I start with (1) I obtain some results, if I start with
> (2) I obtain something different (you can see below the details).
>
> I have also used ElementTransformCleanGroupsOfOne when ElementGroup is
> empty
> ElementTransform transform = new
> ElementTransformCleanGroupsOfOne();
> Element el2 = ElementTransformer.transform(eg, transform);
> return el2;
>
> but no difference in results. I am sure I am doing something wrong.
> Moreover, my questions are: what is the main difference between the two
> approaches? and when I should use ElementGroup arg0 and when List<Element>
> arg1?
>
>
> (1) public Element transform(ElementGroup arg0, List<Element> arg1) {
> List<Element> elemList = arg0.getElements();
> Iterator<Element> itr = elemList.iterator();
> while (itr.hasNext()) {
>
>
> }
> …
> …
> }
>
>
> (2) public Element transform(ElementGroup arg0, List<Element> arg1) {
>
>
>
> Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
>
>
> }
> …
> …
> }
>
> I know that it may be related to the little knowledge about Jena.
> Many Thanks in advice for your clarification on the above.
>
> Best Regards,
> Carlo
>
>
> =======
>
> Below, I reported the used code (at very bottom), the two used scenario
> with test-cases and results. In practice, you can notice that:
>
>
>
> ==== TESTING:
>
> Scenario A:
>
> public Element transform(ElementGroup arg0, List<Element> arg1) {
>
>
>
> List<Element> elemList = arg0.getElements();
> Iterator<Element> itr = elemList.iterator();
> while (itr.hasNext()) {
>
>
> }
> …
> …
> }
>
>
> Test 1:
>
> The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
>
> =========== BEFORE Q1
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>
> SELECT DISTINCT ?name ?mbox
> WHERE
> { ?x foaf:name ?name
> OPTIONAL
> { ?x foaf:mbox ?mbox }
> }
>
>
> ============= AFTER Q1
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>
> SELECT DISTINCT ?name ?mbox
> WHERE
> { ?x foaf:name ?name }
>
>
> Test2:
>
> The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
> query Q2:
>
>
>
> =========== BEFORE Q2
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z
> OPTIONAL
> { ?boss1 ex:isBossOf1 ?ind }
> }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
> }
>
> ============= AFTER Q2: it does not remove the triple.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
> }
>
>
> Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
> Q3:
>
> =========== BEFORE Q3:
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { ?ind rdf:type ?z
> FILTER ( ?ind = "mathieu" )
> }
>
> ============= AFTER Q3: There is still an empty BGP present.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { # Empty BGP
>
>
>
> }
>
>
>
>
>
>
>
>
> Scenario B:
>
> public Element transform(ElementGroup arg0, List<Element> arg1) {
>
>
>
> Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
>
>
> }
> …
> …
> }
>
>
> Test 1:
>
> The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
>
> =========== BEFORE Q1
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>
> SELECT DISTINCT ?name ?mbox
> WHERE
> { ?x foaf:name ?name
> OPTIONAL
> { ?x foaf:mbox ?mbox }
> }
>
>
> ============= AFTER Q1: there is still the OPTION (with a ElementGroup
> empty) clause.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>
> SELECT DISTINCT ?name ?mbox
> WHERE
> { ?x foaf:name ?name
> OPTIONAL
> { # Empty BGP
>
>
>
> }
> }
>
>
>
>
> Test 2:
>
> The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
> query Q2:
>
>
>
> =========== BEFORE Q2
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z
> OPTIONAL
> { ?boss1 ex:isBossOf1 ?ind }
> }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
> }
>
> ============= AFTER Q2: it does not remove the OPTION and it leaves an
> empty BGP.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z
> OPTIONAL
> { # Empty BGP
>
>
>
> }
> }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
> }
>
> Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
> Q3:
>
> =========== BEFORE Q3
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { ?ind rdf:type ?z
> FILTER ( ?ind = "mathieu" )
> }
>
> ============= AFTER Q3: It does not remove the FILTER, but just the triple.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { # Empty BGP
>
>
>
> FILTER ( ?boss = "mathieu" )
> }
> }
>
>
>
>
>
>
>
> === FULL CODE used with public Element transform(ElementPathBlock
> eltPB)
>
> @Override
> public Element transform(ElementPathBlock eltPB) {
> if (eltPB.isEmpty()) {
>
> //System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
> ElementPathBlock IS EMPTY:: " + eltPB.toString());
> return eltPB;
> }
> System.out.println("[RemoveOpTransform::transform(ElementPathBlock
> arg0)] ElementPathBlock:: " + eltPB.toString());
> Iterator<TriplePath> l = eltPB.patternElts();
> while (l.hasNext()) {
> TriplePath tp = l.next();
> if (tp.asTriple().matches(this.triple)) {
> l.remove();
>
> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
> ElementPathBlock:: " + tp.toString() + " TRIPLE JUST REMOVED!!!");
>
> //System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
> TRIPLE JUST REMOVED!!! ");
> System.out.println("");
> return this.transform(eltPB);//eltPB;
> }
> }
> return eltPB;
> }
>
>
> === FULL CODE used with public Element transform(ElementGroup arg0,
> List<Element> arg1)
>
> @Override
> public Element transform(ElementGroup arg0, List<Element> arg1) {
>
>
>
> List<Element> elemList = arg0.getElements();
> Iterator<Element> itr = elemList.iterator();
> //Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
> Element elem = itr.next();
> if (elem instanceof ElementOptional) {
> boolean isElementOptionalEmpty =
> isElementOptionalEmpty((ElementOptional) elem);
> if (isElementOptionalEmpty) {
> itr.remove();
> }
> }
>
> else if (elem instanceof ElementGroup) {
> boolean isElementGroupEmpty =
> isElementGroupEmpty((ElementGroup) elem);
> if (isElementGroupEmpty) {
> itr.remove();
> }
> }
> else if (elem instanceof ElementFilter) {
> //... check if this filter is the one that we should remove
> //...get the variables of the triple pattern that we want
> to delete
> Set<Var> tpVars = new HashSet();
> Node subj = this.triple.getSubject();
> if (subj.isVariable()) {
> tpVars.add((Var) subj);
> }
> Node pred = this.triple.getPredicate();
> if (pred.isVariable()) {
> tpVars.add((Var) pred);
> }
> Node obj = this.triple.getObject();
> if (obj.isVariable()) {
> tpVars.add((Var) obj);
> }
> //...get the variables of the FILTER expression
> Set<Var> expVars = ((ElementFilter)
> elem).getExpr().getVarsMentioned();
> //...check whether the FILTER expression contains any of
> the triple pattern variable
> for (Var var : expVars) {
> //..if it does then we have to delete the entire
> FILTER expression
> if (tpVars.contains(var)) {
> itr.remove();
> }
> }
> }
> else if (elem instanceof ElementUnion) {
> boolean isUnionBothSidesEmpty =
> isUnionBothSidesEmpty1((ElementUnion) elem);
> if (isUnionBothSidesEmpty) {
> itr.remove();
> }
> }
>
> }
> return arg0;
> }
>
>
>
>
>
>
>
>
> On 2 Feb 2016, at 10:54, Carlo.Allocca <ca...@open.ac.uk><mailto:
> carlo.allocca@open.ac.uk<ma...@open.ac.uk>>> wrote:
>
> Dear Andy,
>
> Thank you for your time. Very appreciated.
> Some comments follow in lines.
>
> On 2 Feb 2016, at 09:36, Andy Seaborne <an...@apache.org><mailto:
> andy@apache.org<ma...@apache.org>>> wrote:
>
>
> when removing the triple (?boss ex:isBossOf ?ind .”), I get
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { # Empty BGP
>
> }
> }
> }
>
> which is OK.
> I just need to find out how to remove an ElementGroup which contains only
> one element which is the EMPTY one.
> Of course, I need to do the same for the other case, e.g. OPTION,
> SUBquery, etc.
>
> Do note that evaluating {} (empty syntax group) yields one row of zero
> columns - it contributes to the overall results (it's the join identity).
>
> I see. To avoid this I am going to apply a
> ElementTransformCleanGroupsOfOne as you suggested.
>
>
> Now you have to look at all the elements that have a group in
> ElementUnion, ElementOptional, ElementMinus, …
> Yes, I need to cover all the SPARQL language from the “public Element
> transform(ElementGroup arg0, List<Element> arg1)” call.
> At least this is my understanding so far.
>
>
>
> That is what ElementTransformCleanGroupsOfOne does, except it looks for
> "groups of one"
>
> .. UNION { { stuff } }
>
> and isn't to fussy about finding them all (it's an optimization, more a
> tidying of the tree, not a change in the effect of a query which is what
> removing triple patterns is).
>
> And of course changes from the bottom could potentially cause change all
> the way up to the top of the syntax tree.
>
> also: they maybe be original, legal empty groups in the tree.
>
> Thanks for the detailed clarifications. Indeed, I will consider them.
>
> Many Thanks,
> Best Regards,
> Carlo
>
>
>
> Andy
>
>
>
>
>
>
> -- The Open University is incorporated by Royal Charter (RC 000391), an
> exempt charity in England & Wales and a charity registered in Scotland (SC
> 038302). The Open University is authorised and regulated by the Financial
> Conduct Authority.
>
>
>
>
>
>
> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>
> --
> Lorenz Bühmann
> AKSW group, University of Leipzig
> Group: http://aksw.org<http://aksw.org/> - semantic web research center
>
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Hi Lorenz,
Sorry for this. I tried to use colours to highlight the differences. I left in green my original message, in red Andy answer, and in blue my last reply.
Hope this helps.
Many Thanks,
Carlo
Dear Andy,
Thanks again for your suggesting.
Some comments in line.
On 13 Feb 2016, at 17:04, Andy Seaborne <an...@apache.org>> wrote:
On 04/02/16 19:27, Carlo.Allocca wrote:
Dear Andy and All,
Thank you very much for all your suggestions and willingness.
I went through all of them again and, assembling them (changing a bit the code reported in the previous email)
I got a reasonable first version that is working. But I had to use arg0 instead of arg1 as suggested.
This will get you into trouble!
It probably means something somewhere below is modifying the input structure, not taking a copy.
I will double check and come back to this.
Please, could I ask the followings:
Is there any way to access the aggregate expressions (e.g. GROUP BY or HAVING ) when applying an implementation of ElementTransform?
Look at QueryTransformOps.transform(Query query, ..) which applies transaforms to the thigns that attach to the query object itseld like GROUP.
Thanks. I will try this one and see how to combine with the transform that I have implemented.
Many Thanks,
Best Regards,
Carlo
On 15 Feb 2016, at 11:01, Lorenz Bühmann <bu...@informatik.uni-leipzig.de>> wrote:
Impossible to read as nobody can distinguish between old content and new comments. By the way, the thread is much too long from my point of view
Dear Andy,
Thanks again for your suggesting.
Some comments in line.
On 13 Feb 2016, at 17:04, Andy Seaborne <an...@apache.org>> wrote:
On 04/02/16 19:27, Carlo.Allocca wrote:
Dear Andy and All,
Thank you very much for all your suggestions and willingness.
I went through all of them again and, assembling them (changing a bit the code reported in the previous email)
I got a reasonable first version that is working. But I had to use arg0 instead of arg1 as suggested.
This will get you into trouble!
It probably means something somewhere below is modifying the input structure, not taking a copy.
I will double check and come back to this.
Please, could I ask the followings:
Is there any way to access the aggregate expressions (e.g. GROUP BY or HAVING ) when applying an implementation of ElementTransform?
Look at QueryTransformOps.transform(Query query, ..) which applies transaforms to the thigns that attach to the query object itseld like GROUP.
Thanks. I will try this one and see how to combine with the transform that I have implemented.
Many Thanks,
Best Regards,
Carlo
The reason of such a question is: when applying the operation remove of the triple (?x2 foaf:mbox2 ?mbox2 .) over Q1,
it would make sense to eliminate ORDER BY too as it contains a variable (?x2) from the triple that was eliminated and there no other triple containing such a variable.
Q1:
String qString8 =
SELECT DISTINCT ?x2 ?mbox2 where "
{
?x foaf:name ?name .
?x2 foaf:mbox2 ?mbox2 .
}
ORDER BY ?x2
Many Thanks in advance.
Best Regards,
Carlo
On 3 Feb 2016, at 14:55, Carlo.Allocca <ca...@open.ac.uk>> wrote:
Dear Andy and All,
sorry for this long thread.
I am sure I was not able to put in practice some of your suggestions.
I put the full code here http://collabedit.com/wfhtq and reported below.
I tested it over the Q1 with the triple (?boss ex:isBossOf ?ind).
=========== BEFORE Q1:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
============= AFTER Q1:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ # Empty BGP
FILTER ( ?boss = "mathieu" )
}
}
But the filter is still there even if when I trace the execution it removes it.
I am doing the update between the AST and remove of the filter in
@Override
public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
Element elem = itr.next();
…
...
}
//With this code I am saying the following: make effective all the modifications that //have been made so far, if any.
if (arg0.getElements() == arg1)
{ return arg0; }
else {
ElementGroup el2 = new ElementGroup();
el2.getElements().addAll(arg1);
return el2;
}
}
What am I doing wrong?
Many Thanks for your help.
Best Regards,
Carlo
=== Code
//The main Class
public class RemoveTriple {
public RemoveTriple(){
super();
}
public Query removeTP(Query q, Triple tp) {
RemoveOpTransform rOpTransform = new RemoveOpTransform(q,tp);
Query queryWithoutTriplePattern = QueryTransformOps.transform(q, rOpTransform) ;
return queryWithoutTriplePattern;
}
}
// The current implementation of the RemoveOpTransform class. The class that implements the removal of the triple
public class RemoveOpTransform implements ElementTransform {
private Query query;
private Triple triple;
public RemoveOpTransform(Query q, Triple tp) {
this.query = q;
this.triple = tp;
}
@Override
public Element transform(ElementTriplesBlock arg0) {
System.out.println("[RemoveOpTransform::transform(ElementTriplesBlock arg0)] " + arg0.toString());
System.out.println("");
return arg0;
}
// This is the code related to the
@Override
public Element transform(ElementPathBlock eltPB) {
if (eltPB.isEmpty()) {
return eltPB;
}
Iterator<TriplePath> l = eltPB.patternElts();
while (l.hasNext()) {
TriplePath tp = l.next();
if (tp.asTriple().matches(this.triple)) {
l.remove();
return this.transform(eltPB);//eltPB;
}
}
return eltPB;
}
@Override
public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
Element elem = itr.next();
// I should go one by one the and examinate all the possible cases. For example:
//UNNION
if (elem instanceof ElementUnion) {
if (isUnionBothSidesEmpty) {
itr.remove();
}
}
//OPTION
if (elem instanceof ElementOptional) {
boolean isElementOptionalEmpty = isElementOptionalEmpty((ElementOptional) elem);
if (isElementOptionalEmpty) {
itr.remove();
// ElementGroup el2 = new ElementGroup();
// el2.getElements().addAll(arg1);
// return el2;
}
}
//ELEMENTGROUP
if (elem instanceof ElementGroup) {
boolean isElementGroupEmpty = isElementGroupEmpty((ElementGroup) elem);
if (isElementGroupEmpty) {
itr.remove();
// ElementGroup el2 = new ElementGroup();
// el2.getElements().addAll(arg1);
// return el2;
}
}
//FILTER
if (elem instanceof ElementFilter) {
//... check if this filter is the one that we should remove
//...get the variables of the triple pattern that we want to delete
Set<Var> tpVars = new HashSet();
Node subj = this.triple.getSubject();
if (subj.isVariable()) {
tpVars.add((Var) subj);
}
Node pred = this.triple.getPredicate();
if (pred.isVariable()) {
tpVars.add((Var) pred);
}
Node obj = this.triple.getObject();
if (obj.isVariable()) {
tpVars.add((Var) obj);
}
//...get the variables of the FILTER expression
Set<Var> expVars = ((ElementFilter) elem).getExpr().getVarsMentioned();
//...check whether the FILTER expression contains any of the triple pattern variable
for (Var var : expVars) {
//...if it does then we can delete the entire FILTER expression
if (tpVars.contains(var)) {
itr.remove();
break;
}
}
}
}// End of While
//With this code I am saying the following: make effective all the modifications that
//have been made so far, if any.
if (arg0.getElements() == arg1) {
return arg0;
} else {
ElementGroup el2 = new ElementGroup();
el2.getElements().addAll(arg1);
return el2;
}
}
@Override
public Element transform(ElementFilter arg0, Expr arg1) {
return arg0;
}
@Override
public Element transform(ElementAssign arg0, Var arg1, Expr arg2) {
return arg0;
}
@Override
public Element transform(ElementBind arg0, Var arg1, Expr arg2) {
System.out.println("[RemoveOpTransform::transform(ElementBind arg0)] " + arg0.toString());
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementData arg0) {
System.out.println("[RemoveOpTransform::transform(ElementData arg0)] " + arg0.toString());
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementDataset arg0, Element arg1) {
System.out.println("[RemoveOpTransform::transform(ElementDataset arg0)] " + arg0.toString());
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementUnion arg0, List<Element> arg1) {
System.out.println("[RemoveOpTransform::transform(ElementUnion arg0)] arg0 " + arg0.toString());
System.out.println("[RemoveOpTransform::transform(ElementUnion arg0)] arg1 " + arg1.toString());
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementOptional arg0, Element arg1) {
return arg0;
}
@Override
public Element transform(ElementNamedGraph arg0, Node arg1, Element arg2) {
System.out.println("[RemoveOpTransform::transform(ElementNamedGraph arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementExists arg0, Element arg1) {
System.out.println("[RemoveOpTransform::transform(ElementExists arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementNotExists arg0, Element arg1) {
System.out.println("[RemoveOpTransform::transform(ElementNotExists arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementMinus arg0, Element arg1) {
System.out.println("[RemoveOpTransform::transform(ElementMinus arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementService arg0, Node arg1, Element arg2) {
System.out.println("[RemoveOpTransform::transform(ElementService arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementSubQuery arg0, Query arg1) {
System.out.println("[RemoveOpTransform::transform(ElementSubQuery arg0)] ");
System.out.println("");
return arg0;
}
private boolean isUnionBothSidesEmpty1(ElementUnion elementUnion) {
List<Element> elemListUnion = elementUnion.getElements();//.getElements();
if (elemListUnion.size() == 2) {
Element left = elemListUnion.get(0);
Element right = elemListUnion.get(1);
if (left instanceof ElementGroup && right instanceof ElementGroup) {
if ((((ElementGroup) left).getElements().size() == 1) && (((ElementGroup) right).getElements().size() == 1)) {
Element elLeft = ((ElementGroup) left).getElements().get(0);
Element elRight = ((ElementGroup) right).getElements().get(0);
if ((elLeft instanceof ElementPathBlock) && (elRight instanceof ElementPathBlock)) {
ElementPathBlock epbLeft = (ElementPathBlock) elLeft;
ElementPathBlock epbRight = (ElementPathBlock) elRight;
if (epbLeft.isEmpty() && epbRight.isEmpty()) {
return true;
}
}
}
}
}
return false;
}
private boolean isElementGroupEmpty(ElementGroup elementGroup) {
List<Element> elList = ((ElementGroup) elementGroup).getElements();
if (elList.size() == 1) {
Element el = (Element) elList.get(0);
if (el instanceof ElementPathBlock) {
ElementPathBlock tmp = (ElementPathBlock) el;
if (tmp.isEmpty()) {
return true;
}
}
}
return false;
}
private boolean isElementOptionalEmpty(ElementOptional elementOptional) {
Element elm = ((ElementOptional) elementOptional).getOptionalElement();//.getElements();
if (elm instanceof ElementGroup) {
List<Element> elList = ((ElementGroup) elm).getElements();
if (elList.size() == 1) {
Element el = (Element) elList.get(0);
if (el instanceof ElementPathBlock) {
ElementPathBlock tmp = (ElementPathBlock) el;
if (tmp.isEmpty()) {
return true;
}
}
}
}
return false;
}
}
On 3 Feb 2016, at 00:00, Carlo.Allocca <ca...@open.ac.uk>> wrote:
Dear Andy and Paul,
some comments follow in lines.
On 2 Feb 2016, at 22:33, Andy Seaborne <an...@apache.org>> wrote:
On 02/02/16 19:29, Paul Houle wrote:
Carlo, Andy,
I like the Iterator<> interfaces in the Jena framework for getting data
out, but I make a habit of always putting results in a List or Queue or
something before putting them back into the same Jena model because i get
less BS per mile that way in terms of Exceptions and other exceptional
events.
Does Jena have an official policy on being reenterable in that way?
Carlo's issues are nothing to do with iterator policy.
Carlo - Use arg1 else you will not see your changes so far.
In
public Element transform(ElementGroup arg0, List<Element> arg1)
arg0 is the element from the AST before modification and
arg1 is the new elements to go in after modification by lower levels of the bottom-up rewrite.
So if you rewrite a ElementFilter by making a new one, it will appear in arg1 not in arg0.
I see. Thank you. Based on this, I am going to use "Iterator<Element> itr = arg1.iterator(); when implementing
public Element transform(ElementGroup arg0, List<Element> arg1).
Do not modify the Element* arguments in place.
See ElementTransformCopyBase
The default implementation is:
@Override
public Element transform(ElementGroup el, List<Element> elts) {
if ( el.getElements() == elts )
return el ;
ElementGroup el2 = new ElementGroup() ;
el2.getElements().addAll(elts) ;
return el2 ;
}
i.e if any change, detected by being not the exact identical list, then do a copy of the structure. This saves object churn.
I am going to change my implementation in such a way include all the above suggestions and clarifications.
Many Thanks for your willingness.
Best Regards,
Carlo.
Andy
On Tue, Feb 2, 2016 at 2:13 PM, Carlo.Allocca <ca...@open.ac.uk>>
wrote:
Dear Andy and All,
while I was extending and testing the code that I wrote so far concerning
the removing a triple from a given SPARQL query,
I realised that I get different outputs depending on how I start the
implementation of the public Element transform(ElementGroup arg0,
List<Element> arg1).
In particular, if I start with (1) I obtain some results, if I start with
(2) I obtain something different (you can see below the details).
I have also used ElementTransformCleanGroupsOfOne when ElementGroup is
empty
ElementTransform transform = new
ElementTransformCleanGroupsOfOne();
Element el2 = ElementTransformer.transform(eg, transform);
return el2;
but no difference in results. I am sure I am doing something wrong.
Moreover, my questions are: what is the main difference between the two
approaches? and when I should use ElementGroup arg0 and when List<Element>
arg1?
(1) public Element transform(ElementGroup arg0, List<Element> arg1) {
List<Element> elemList = arg0.getElements();
Iterator<Element> itr = elemList.iterator();
while (itr.hasNext()) {
}
…
…
}
(2) public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
}
…
…
}
I know that it may be related to the little knowledge about Jena.
Many Thanks in advice for your clarification on the above.
Best Regards,
Carlo
=======
Below, I reported the used code (at very bottom), the two used scenario
with test-cases and results. In practice, you can notice that:
==== TESTING:
Scenario A:
public Element transform(ElementGroup arg0, List<Element> arg1) {
List<Element> elemList = arg0.getElements();
Iterator<Element> itr = elemList.iterator();
while (itr.hasNext()) {
}
…
…
}
Test 1:
The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
=========== BEFORE Q1
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name
OPTIONAL
{ ?x foaf:mbox ?mbox }
}
============= AFTER Q1
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name }
Test2:
The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
query Q2:
=========== BEFORE Q2
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z
OPTIONAL
{ ?boss1 ex:isBossOf1 ?ind }
}
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
============= AFTER Q2: it does not remove the triple.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
Q3:
=========== BEFORE Q3:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ ?ind rdf:type ?z
FILTER ( ?ind = "mathieu" )
}
============= AFTER Q3: There is still an empty BGP present.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ # Empty BGP
}
Scenario B:
public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
}
…
…
}
Test 1:
The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
=========== BEFORE Q1
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name
OPTIONAL
{ ?x foaf:mbox ?mbox }
}
============= AFTER Q1: there is still the OPTION (with a ElementGroup
empty) clause.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name
OPTIONAL
{ # Empty BGP
}
}
Test 2:
The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
query Q2:
=========== BEFORE Q2
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z
OPTIONAL
{ ?boss1 ex:isBossOf1 ?ind }
}
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
============= AFTER Q2: it does not remove the OPTION and it leaves an
empty BGP.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z
OPTIONAL
{ # Empty BGP
}
}
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
Q3:
=========== BEFORE Q3
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ ?ind rdf:type ?z
FILTER ( ?ind = "mathieu" )
}
============= AFTER Q3: It does not remove the FILTER, but just the triple.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ # Empty BGP
FILTER ( ?boss = "mathieu" )
}
}
=== FULL CODE used with public Element transform(ElementPathBlock
eltPB)
@Override
public Element transform(ElementPathBlock eltPB) {
if (eltPB.isEmpty()) {
//System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
ElementPathBlock IS EMPTY:: " + eltPB.toString());
return eltPB;
}
System.out.println("[RemoveOpTransform::transform(ElementPathBlock
arg0)] ElementPathBlock:: " + eltPB.toString());
Iterator<TriplePath> l = eltPB.patternElts();
while (l.hasNext()) {
TriplePath tp = l.next();
if (tp.asTriple().matches(this.triple)) {
l.remove();
System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
ElementPathBlock:: " + tp.toString() + " TRIPLE JUST REMOVED!!!");
//System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
TRIPLE JUST REMOVED!!! ");
System.out.println("");
return this.transform(eltPB);//eltPB;
}
}
return eltPB;
}
=== FULL CODE used with public Element transform(ElementGroup arg0,
List<Element> arg1)
@Override
public Element transform(ElementGroup arg0, List<Element> arg1) {
List<Element> elemList = arg0.getElements();
Iterator<Element> itr = elemList.iterator();
//Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
Element elem = itr.next();
if (elem instanceof ElementOptional) {
boolean isElementOptionalEmpty =
isElementOptionalEmpty((ElementOptional) elem);
if (isElementOptionalEmpty) {
itr.remove();
}
}
else if (elem instanceof ElementGroup) {
boolean isElementGroupEmpty =
isElementGroupEmpty((ElementGroup) elem);
if (isElementGroupEmpty) {
itr.remove();
}
}
else if (elem instanceof ElementFilter) {
//... check if this filter is the one that we should remove
//...get the variables of the triple pattern that we want
to delete
Set<Var> tpVars = new HashSet();
Node subj = this.triple.getSubject();
if (subj.isVariable()) {
tpVars.add((Var) subj);
}
Node pred = this.triple.getPredicate();
if (pred.isVariable()) {
tpVars.add((Var) pred);
}
Node obj = this.triple.getObject();
if (obj.isVariable()) {
tpVars.add((Var) obj);
}
//...get the variables of the FILTER expression
Set<Var> expVars = ((ElementFilter)
elem).getExpr().getVarsMentioned();
//...check whether the FILTER expression contains any of
the triple pattern variable
for (Var var : expVars) {
//..if it does then we have to delete the entire
FILTER expression
if (tpVars.contains(var)) {
itr.remove();
}
}
}
else if (elem instanceof ElementUnion) {
boolean isUnionBothSidesEmpty =
isUnionBothSidesEmpty1((ElementUnion) elem);
if (isUnionBothSidesEmpty) {
itr.remove();
}
}
}
return arg0;
}
On 2 Feb 2016, at 10:54, Carlo.Allocca <ca...@open.ac.uk><mailto:
carlo.allocca@open.ac.uk<ma...@open.ac.uk>>> wrote:
Dear Andy,
Thank you for your time. Very appreciated.
Some comments follow in lines.
On 2 Feb 2016, at 09:36, Andy Seaborne <an...@apache.org><mailto:
andy@apache.org<ma...@apache.org>>> wrote:
when removing the triple (?boss ex:isBossOf ?ind .”), I get
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ # Empty BGP
}
}
}
which is OK.
I just need to find out how to remove an ElementGroup which contains only
one element which is the EMPTY one.
Of course, I need to do the same for the other case, e.g. OPTION,
SUBquery, etc.
Do note that evaluating {} (empty syntax group) yields one row of zero
columns - it contributes to the overall results (it's the join identity).
I see. To avoid this I am going to apply a
ElementTransformCleanGroupsOfOne as you suggested.
Now you have to look at all the elements that have a group in
ElementUnion, ElementOptional, ElementMinus, …
Yes, I need to cover all the SPARQL language from the “public Element
transform(ElementGroup arg0, List<Element> arg1)” call.
At least this is my understanding so far.
That is what ElementTransformCleanGroupsOfOne does, except it looks for
"groups of one"
.. UNION { { stuff } }
and isn't to fussy about finding them all (it's an optimization, more a
tidying of the tree, not a change in the effect of a query which is what
removing triple patterns is).
And of course changes from the bottom could potentially cause change all
the way up to the top of the syntax tree.
also: they maybe be original, legal empty groups in the tree.
Thanks for the detailed clarifications. Indeed, I will consider them.
Many Thanks,
Best Regards,
Carlo
Andy
-- The Open University is incorporated by Royal Charter (RC 000391), an
exempt charity in England & Wales and a charity registered in Scotland (SC
038302). The Open University is authorised and regulated by the Financial
Conduct Authority.
-- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
--
Lorenz Bühmann
AKSW group, University of Leipzig
Group: http://aksw.org<http://aksw.org/> - semantic web research center
Re: How to remove consistently a triple pattern given a SPARQL query?
Posted by Lorenz Bühmann <bu...@informatik.uni-leipzig.de>.
Impossible to read as nobody can distinguish between old content and new
comments. By the way, the thread is much too long from my point of view
> Dear Andy,
>
> Thanks again for your suggesting.
> Some comments in line.
>
> On 13 Feb 2016, at 17:04, Andy Seaborne <an...@apache.org>> wrote:
>
> On 04/02/16 19:27, Carlo.Allocca wrote:
> Dear Andy and All,
>
> Thank you very much for all your suggestions and willingness.
>
> I went through all of them again and, assembling them (changing a bit the code reported in the previous email)
> I got a reasonable first version that is working. But I had to use arg0 instead of arg1 as suggested.
>
> This will get you into trouble!
>
> It probably means something somewhere below is modifying the input structure, not taking a copy.
> I will double check and come back to this.
>
>
>
> Please, could I ask the followings:
>
> Is there any way to access the aggregate expressions (e.g. GROUP BY or HAVING ) when applying an implementation of ElementTransform?
>
> Look at QueryTransformOps.transform(Query query, ..) which applies transaforms to the thigns that attach to the query object itseld like GROUP.
>
> Thanks. I will try this one and see how to combine with the transform that I have implemented.
>
> Many Thanks,
> Best Regards,
> Carlo
>
>
> The reason of such a question is: when applying the operation remove of the triple (?x2 foaf:mbox2 ?mbox2 .) over Q1,
> it would make sense to eliminate ORDER BY too as it contains a variable (?x2) from the triple that was eliminated and there no other triple containing such a variable.
>
> Q1:
>
> String qString8 =
> SELECT DISTINCT ?x2 ?mbox2 where "
> {
> ?x foaf:name ?name .
> ?x2 foaf:mbox2 ?mbox2 .
> }
> ORDER BY ?x2
>
>
> Many Thanks in advance.
> Best Regards,
> Carlo
>
>
>
>
> On 3 Feb 2016, at 14:55, Carlo.Allocca <ca...@open.ac.uk>> wrote:
>
> Dear Andy and All,
>
> sorry for this long thread.
> I am sure I was not able to put in practice some of your suggestions.
>
> I put the full code here http://collabedit.com/wfhtq and reported below.
>
> I tested it over the Q1 with the triple (?boss ex:isBossOf ?ind).
>
> =========== BEFORE Q1:
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
>
>
>
> ============= AFTER Q1:
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { # Empty BGP
>
> FILTER ( ?boss = "mathieu" )
> }
> }
>
>
> But the filter is still there even if when I trace the execution it removes it.
> I am doing the update between the AST and remove of the filter in
>
> @Override
> public Element transform(ElementGroup arg0, List<Element> arg1) {
> Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
> Element elem = itr.next();
> …
> ...
> }
>
> //With this code I am saying the following: make effective all the modifications that //have been made so far, if any.
> if (arg0.getElements() == arg1)
> { return arg0; }
> else {
> ElementGroup el2 = new ElementGroup();
> el2.getElements().addAll(arg1);
> return el2;
> }
>
> }
>
>
> What am I doing wrong?
>
> Many Thanks for your help.
>
> Best Regards,
> Carlo
>
>
>
>
>
> === Code
>
> //The main Class
>
> public class RemoveTriple {
>
> public RemoveTriple(){
> super();
> }
>
> public Query removeTP(Query q, Triple tp) {
> RemoveOpTransform rOpTransform = new RemoveOpTransform(q,tp);
> Query queryWithoutTriplePattern = QueryTransformOps.transform(q, rOpTransform) ;
> return queryWithoutTriplePattern;
> }
> }
>
> // The current implementation of the RemoveOpTransform class. The class that implements the removal of the triple
>
> public class RemoveOpTransform implements ElementTransform {
>
> private Query query;
> private Triple triple;
>
> public RemoveOpTransform(Query q, Triple tp) {
> this.query = q;
> this.triple = tp;
> }
>
> @Override
> public Element transform(ElementTriplesBlock arg0) {
> System.out.println("[RemoveOpTransform::transform(ElementTriplesBlock arg0)] " + arg0.toString());
> System.out.println("");
> return arg0;
> }
>
> // This is the code related to the
> @Override
> public Element transform(ElementPathBlock eltPB) {
> if (eltPB.isEmpty()) {
> return eltPB;
> }
> Iterator<TriplePath> l = eltPB.patternElts();
> while (l.hasNext()) {
> TriplePath tp = l.next();
> if (tp.asTriple().matches(this.triple)) {
> l.remove();
> return this.transform(eltPB);//eltPB;
> }
> }
> return eltPB;
> }
>
>
> @Override
> public Element transform(ElementGroup arg0, List<Element> arg1) {
>
> Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
> Element elem = itr.next();
> // I should go one by one the and examinate all the possible cases. For example:
>
> //UNNION
> if (elem instanceof ElementUnion) {
> if (isUnionBothSidesEmpty) {
> itr.remove();
> }
> }
>
> //OPTION
> if (elem instanceof ElementOptional) {
> boolean isElementOptionalEmpty = isElementOptionalEmpty((ElementOptional) elem);
> if (isElementOptionalEmpty) {
> itr.remove();
> // ElementGroup el2 = new ElementGroup();
> // el2.getElements().addAll(arg1);
> // return el2;
> }
> }
>
> //ELEMENTGROUP
> if (elem instanceof ElementGroup) {
> boolean isElementGroupEmpty = isElementGroupEmpty((ElementGroup) elem);
> if (isElementGroupEmpty) {
> itr.remove();
> // ElementGroup el2 = new ElementGroup();
> // el2.getElements().addAll(arg1);
> // return el2;
> }
> }
>
> //FILTER
> if (elem instanceof ElementFilter) {
> //... check if this filter is the one that we should remove
> //...get the variables of the triple pattern that we want to delete
> Set<Var> tpVars = new HashSet();
> Node subj = this.triple.getSubject();
> if (subj.isVariable()) {
> tpVars.add((Var) subj);
> }
> Node pred = this.triple.getPredicate();
> if (pred.isVariable()) {
> tpVars.add((Var) pred);
> }
> Node obj = this.triple.getObject();
> if (obj.isVariable()) {
> tpVars.add((Var) obj);
> }
> //...get the variables of the FILTER expression
> Set<Var> expVars = ((ElementFilter) elem).getExpr().getVarsMentioned();
> //...check whether the FILTER expression contains any of the triple pattern variable
> for (Var var : expVars) {
> //...if it does then we can delete the entire FILTER expression
> if (tpVars.contains(var)) {
> itr.remove();
> break;
> }
> }
> }
>
> }// End of While
>
> //With this code I am saying the following: make effective all the modifications that
> //have been made so far, if any.
> if (arg0.getElements() == arg1) {
> return arg0;
> } else {
> ElementGroup el2 = new ElementGroup();
> el2.getElements().addAll(arg1);
> return el2;
> }
> }
>
>
>
>
> @Override
> public Element transform(ElementFilter arg0, Expr arg1) {
> return arg0;
> }
>
> @Override
> public Element transform(ElementAssign arg0, Var arg1, Expr arg2) {
> return arg0;
> }
>
> @Override
> public Element transform(ElementBind arg0, Var arg1, Expr arg2) {
> System.out.println("[RemoveOpTransform::transform(ElementBind arg0)] " + arg0.toString());
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementData arg0) {
> System.out.println("[RemoveOpTransform::transform(ElementData arg0)] " + arg0.toString());
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementDataset arg0, Element arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementDataset arg0)] " + arg0.toString());
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementUnion arg0, List<Element> arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementUnion arg0)] arg0 " + arg0.toString());
> System.out.println("[RemoveOpTransform::transform(ElementUnion arg0)] arg1 " + arg1.toString());
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementOptional arg0, Element arg1) {
> return arg0;
> }
>
> @Override
> public Element transform(ElementNamedGraph arg0, Node arg1, Element arg2) {
> System.out.println("[RemoveOpTransform::transform(ElementNamedGraph arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementExists arg0, Element arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementExists arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementNotExists arg0, Element arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementNotExists arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementMinus arg0, Element arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementMinus arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementService arg0, Node arg1, Element arg2) {
> System.out.println("[RemoveOpTransform::transform(ElementService arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementSubQuery arg0, Query arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementSubQuery arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> private boolean isUnionBothSidesEmpty1(ElementUnion elementUnion) {
> List<Element> elemListUnion = elementUnion.getElements();//.getElements();
> if (elemListUnion.size() == 2) {
> Element left = elemListUnion.get(0);
> Element right = elemListUnion.get(1);
> if (left instanceof ElementGroup && right instanceof ElementGroup) {
> if ((((ElementGroup) left).getElements().size() == 1) && (((ElementGroup) right).getElements().size() == 1)) {
> Element elLeft = ((ElementGroup) left).getElements().get(0);
> Element elRight = ((ElementGroup) right).getElements().get(0);
> if ((elLeft instanceof ElementPathBlock) && (elRight instanceof ElementPathBlock)) {
> ElementPathBlock epbLeft = (ElementPathBlock) elLeft;
> ElementPathBlock epbRight = (ElementPathBlock) elRight;
> if (epbLeft.isEmpty() && epbRight.isEmpty()) {
> return true;
> }
> }
> }
> }
> }
> return false;
> }
>
> private boolean isElementGroupEmpty(ElementGroup elementGroup) {
> List<Element> elList = ((ElementGroup) elementGroup).getElements();
> if (elList.size() == 1) {
> Element el = (Element) elList.get(0);
> if (el instanceof ElementPathBlock) {
> ElementPathBlock tmp = (ElementPathBlock) el;
> if (tmp.isEmpty()) {
> return true;
> }
> }
> }
> return false;
> }
>
> private boolean isElementOptionalEmpty(ElementOptional elementOptional) {
> Element elm = ((ElementOptional) elementOptional).getOptionalElement();//.getElements();
> if (elm instanceof ElementGroup) {
> List<Element> elList = ((ElementGroup) elm).getElements();
> if (elList.size() == 1) {
> Element el = (Element) elList.get(0);
> if (el instanceof ElementPathBlock) {
> ElementPathBlock tmp = (ElementPathBlock) el;
> if (tmp.isEmpty()) {
> return true;
> }
> }
> }
> }
> return false;
> }
>
> }
>
>
>
>
>
>
>
>
> On 3 Feb 2016, at 00:00, Carlo.Allocca <ca...@open.ac.uk>> wrote:
>
> Dear Andy and Paul,
>
> some comments follow in lines.
>
> On 2 Feb 2016, at 22:33, Andy Seaborne <an...@apache.org>> wrote:
>
> On 02/02/16 19:29, Paul Houle wrote:
> Carlo, Andy,
>
> I like the Iterator<> interfaces in the Jena framework for getting data
> out, but I make a habit of always putting results in a List or Queue or
> something before putting them back into the same Jena model because i get
> less BS per mile that way in terms of Exceptions and other exceptional
> events.
>
> Does Jena have an official policy on being reenterable in that way?
>
> Carlo's issues are nothing to do with iterator policy.
>
> Carlo - Use arg1 else you will not see your changes so far.
>
> In
>
> public Element transform(ElementGroup arg0, List<Element> arg1)
>
> arg0 is the element from the AST before modification and
> arg1 is the new elements to go in after modification by lower levels of the bottom-up rewrite.
>
>
> So if you rewrite a ElementFilter by making a new one, it will appear in arg1 not in arg0.
> I see. Thank you. Based on this, I am going to use "Iterator<Element> itr = arg1.iterator(); when implementing
> public Element transform(ElementGroup arg0, List<Element> arg1).
>
>
>
> Do not modify the Element* arguments in place.
>
>
> See ElementTransformCopyBase
>
> The default implementation is:
>
> @Override
> public Element transform(ElementGroup el, List<Element> elts) {
> if ( el.getElements() == elts )
> return el ;
> ElementGroup el2 = new ElementGroup() ;
> el2.getElements().addAll(elts) ;
> return el2 ;
> }
>
>
> i.e if any change, detected by being not the exact identical list, then do a copy of the structure. This saves object churn.
>
> I am going to change my implementation in such a way include all the above suggestions and clarifications.
>
> Many Thanks for your willingness.
> Best Regards,
> Carlo.
>
>
> Andy
>
>
> On Tue, Feb 2, 2016 at 2:13 PM, Carlo.Allocca <ca...@open.ac.uk>>
> wrote:
>
>
> Dear Andy and All,
>
> while I was extending and testing the code that I wrote so far concerning
> the removing a triple from a given SPARQL query,
> I realised that I get different outputs depending on how I start the
> implementation of the public Element transform(ElementGroup arg0,
> List<Element> arg1).
> In particular, if I start with (1) I obtain some results, if I start with
> (2) I obtain something different (you can see below the details).
>
> I have also used ElementTransformCleanGroupsOfOne when ElementGroup is
> empty
> ElementTransform transform = new
> ElementTransformCleanGroupsOfOne();
> Element el2 = ElementTransformer.transform(eg, transform);
> return el2;
>
> but no difference in results. I am sure I am doing something wrong.
> Moreover, my questions are: what is the main difference between the two
> approaches? and when I should use ElementGroup arg0 and when List<Element>
> arg1?
>
>
> (1) public Element transform(ElementGroup arg0, List<Element> arg1) {
> List<Element> elemList = arg0.getElements();
> Iterator<Element> itr = elemList.iterator();
> while (itr.hasNext()) {
>
>
> }
> …
> …
> }
>
>
> (2) public Element transform(ElementGroup arg0, List<Element> arg1) {
>
>
>
> Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
>
>
> }
> …
> …
> }
>
> I know that it may be related to the little knowledge about Jena.
> Many Thanks in advice for your clarification on the above.
>
> Best Regards,
> Carlo
>
>
> =======
>
> Below, I reported the used code (at very bottom), the two used scenario
> with test-cases and results. In practice, you can notice that:
>
>
>
> ==== TESTING:
>
> Scenario A:
>
> public Element transform(ElementGroup arg0, List<Element> arg1) {
>
>
>
> List<Element> elemList = arg0.getElements();
> Iterator<Element> itr = elemList.iterator();
> while (itr.hasNext()) {
>
>
> }
> …
> …
> }
>
>
> Test 1:
>
> The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
>
> =========== BEFORE Q1
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>
> SELECT DISTINCT ?name ?mbox
> WHERE
> { ?x foaf:name ?name
> OPTIONAL
> { ?x foaf:mbox ?mbox }
> }
>
>
> ============= AFTER Q1
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>
> SELECT DISTINCT ?name ?mbox
> WHERE
> { ?x foaf:name ?name }
>
>
> Test2:
>
> The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
> query Q2:
>
>
>
> =========== BEFORE Q2
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z
> OPTIONAL
> { ?boss1 ex:isBossOf1 ?ind }
> }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
> }
>
> ============= AFTER Q2: it does not remove the triple.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
> }
>
>
> Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
> Q3:
>
> =========== BEFORE Q3:
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { ?ind rdf:type ?z
> FILTER ( ?ind = "mathieu" )
> }
>
> ============= AFTER Q3: There is still an empty BGP present.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { # Empty BGP
>
>
>
> }
>
>
>
>
>
>
>
>
> Scenario B:
>
> public Element transform(ElementGroup arg0, List<Element> arg1) {
>
>
>
> Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
>
>
> }
> …
> …
> }
>
>
> Test 1:
>
> The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
>
> =========== BEFORE Q1
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>
> SELECT DISTINCT ?name ?mbox
> WHERE
> { ?x foaf:name ?name
> OPTIONAL
> { ?x foaf:mbox ?mbox }
> }
>
>
> ============= AFTER Q1: there is still the OPTION (with a ElementGroup
> empty) clause.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>
> SELECT DISTINCT ?name ?mbox
> WHERE
> { ?x foaf:name ?name
> OPTIONAL
> { # Empty BGP
>
>
>
> }
> }
>
>
>
>
> Test 2:
>
> The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
> query Q2:
>
>
>
> =========== BEFORE Q2
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z
> OPTIONAL
> { ?boss1 ex:isBossOf1 ?ind }
> }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
> }
>
> ============= AFTER Q2: it does not remove the OPTION and it leaves an
> empty BGP.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z
> OPTIONAL
> { # Empty BGP
>
>
>
> }
> }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
> }
>
> Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
> Q3:
>
> =========== BEFORE Q3
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { ?ind rdf:type ?z
> FILTER ( ?ind = "mathieu" )
> }
>
> ============= AFTER Q3: It does not remove the FILTER, but just the triple.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { # Empty BGP
>
>
>
> FILTER ( ?boss = "mathieu" )
> }
> }
>
>
>
>
>
>
>
> === FULL CODE used with public Element transform(ElementPathBlock
> eltPB)
>
> @Override
> public Element transform(ElementPathBlock eltPB) {
> if (eltPB.isEmpty()) {
>
> //System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
> ElementPathBlock IS EMPTY:: " + eltPB.toString());
> return eltPB;
> }
> System.out.println("[RemoveOpTransform::transform(ElementPathBlock
> arg0)] ElementPathBlock:: " + eltPB.toString());
> Iterator<TriplePath> l = eltPB.patternElts();
> while (l.hasNext()) {
> TriplePath tp = l.next();
> if (tp.asTriple().matches(this.triple)) {
> l.remove();
>
> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
> ElementPathBlock:: " + tp.toString() + " TRIPLE JUST REMOVED!!!");
>
> //System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
> TRIPLE JUST REMOVED!!! ");
> System.out.println("");
> return this.transform(eltPB);//eltPB;
> }
> }
> return eltPB;
> }
>
>
> === FULL CODE used with public Element transform(ElementGroup arg0,
> List<Element> arg1)
>
> @Override
> public Element transform(ElementGroup arg0, List<Element> arg1) {
>
>
>
> List<Element> elemList = arg0.getElements();
> Iterator<Element> itr = elemList.iterator();
> //Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
> Element elem = itr.next();
> if (elem instanceof ElementOptional) {
> boolean isElementOptionalEmpty =
> isElementOptionalEmpty((ElementOptional) elem);
> if (isElementOptionalEmpty) {
> itr.remove();
> }
> }
>
> else if (elem instanceof ElementGroup) {
> boolean isElementGroupEmpty =
> isElementGroupEmpty((ElementGroup) elem);
> if (isElementGroupEmpty) {
> itr.remove();
> }
> }
> else if (elem instanceof ElementFilter) {
> //... check if this filter is the one that we should remove
> //...get the variables of the triple pattern that we want
> to delete
> Set<Var> tpVars = new HashSet();
> Node subj = this.triple.getSubject();
> if (subj.isVariable()) {
> tpVars.add((Var) subj);
> }
> Node pred = this.triple.getPredicate();
> if (pred.isVariable()) {
> tpVars.add((Var) pred);
> }
> Node obj = this.triple.getObject();
> if (obj.isVariable()) {
> tpVars.add((Var) obj);
> }
> //...get the variables of the FILTER expression
> Set<Var> expVars = ((ElementFilter)
> elem).getExpr().getVarsMentioned();
> //...check whether the FILTER expression contains any of
> the triple pattern variable
> for (Var var : expVars) {
> //..if it does then we have to delete the entire
> FILTER expression
> if (tpVars.contains(var)) {
> itr.remove();
> }
> }
> }
> else if (elem instanceof ElementUnion) {
> boolean isUnionBothSidesEmpty =
> isUnionBothSidesEmpty1((ElementUnion) elem);
> if (isUnionBothSidesEmpty) {
> itr.remove();
> }
> }
>
> }
> return arg0;
> }
>
>
>
>
>
>
>
>
> On 2 Feb 2016, at 10:54, Carlo.Allocca <ca...@open.ac.uk><mailto:
> carlo.allocca@open.ac.uk<ma...@open.ac.uk>>> wrote:
>
> Dear Andy,
>
> Thank you for your time. Very appreciated.
> Some comments follow in lines.
>
> On 2 Feb 2016, at 09:36, Andy Seaborne <an...@apache.org><mailto:
> andy@apache.org<ma...@apache.org>>> wrote:
>
>
> when removing the triple (?boss ex:isBossOf ?ind .”), I get
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { # Empty BGP
>
> }
> }
> }
>
> which is OK.
> I just need to find out how to remove an ElementGroup which contains only
> one element which is the EMPTY one.
> Of course, I need to do the same for the other case, e.g. OPTION,
> SUBquery, etc.
>
> Do note that evaluating {} (empty syntax group) yields one row of zero
> columns - it contributes to the overall results (it's the join identity).
>
> I see. To avoid this I am going to apply a
> ElementTransformCleanGroupsOfOne as you suggested.
>
>
> Now you have to look at all the elements that have a group in
> ElementUnion, ElementOptional, ElementMinus, …
> Yes, I need to cover all the SPARQL language from the “public Element
> transform(ElementGroup arg0, List<Element> arg1)” call.
> At least this is my understanding so far.
>
>
>
> That is what ElementTransformCleanGroupsOfOne does, except it looks for
> "groups of one"
>
> .. UNION { { stuff } }
>
> and isn't to fussy about finding them all (it's an optimization, more a
> tidying of the tree, not a change in the effect of a query which is what
> removing triple patterns is).
>
> And of course changes from the bottom could potentially cause change all
> the way up to the top of the syntax tree.
>
> also: they maybe be original, legal empty groups in the tree.
>
> Thanks for the detailed clarifications. Indeed, I will consider them.
>
> Many Thanks,
> Best Regards,
> Carlo
>
>
>
> Andy
>
>
>
>
>
>
> -- The Open University is incorporated by Royal Charter (RC 000391), an
> exempt charity in England & Wales and a charity registered in Scotland (SC
> 038302). The Open University is authorised and regulated by the Financial
> Conduct Authority.
>
>
>
>
>
>
> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>
--
Lorenz Bühmann
AKSW group, University of Leipzig
Group: http://aksw.org - semantic web research center
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Dear Andy,
Thanks again for your suggesting.
Some comments in line.
On 13 Feb 2016, at 17:04, Andy Seaborne <an...@apache.org>> wrote:
On 04/02/16 19:27, Carlo.Allocca wrote:
Dear Andy and All,
Thank you very much for all your suggestions and willingness.
I went through all of them again and, assembling them (changing a bit the code reported in the previous email)
I got a reasonable first version that is working. But I had to use arg0 instead of arg1 as suggested.
This will get you into trouble!
It probably means something somewhere below is modifying the input structure, not taking a copy.
I will double check and come back to this.
Please, could I ask the followings:
Is there any way to access the aggregate expressions (e.g. GROUP BY or HAVING ) when applying an implementation of ElementTransform?
Look at QueryTransformOps.transform(Query query, ..) which applies transaforms to the thigns that attach to the query object itseld like GROUP.
Thanks. I will try this one and see how to combine with the transform that I have implemented.
Many Thanks,
Best Regards,
Carlo
The reason of such a question is: when applying the operation remove of the triple (?x2 foaf:mbox2 ?mbox2 .) over Q1,
it would make sense to eliminate ORDER BY too as it contains a variable (?x2) from the triple that was eliminated and there no other triple containing such a variable.
Q1:
String qString8 =
SELECT DISTINCT ?x2 ?mbox2 where "
{
?x foaf:name ?name .
?x2 foaf:mbox2 ?mbox2 .
}
ORDER BY ?x2
Many Thanks in advance.
Best Regards,
Carlo
On 3 Feb 2016, at 14:55, Carlo.Allocca <ca...@open.ac.uk>> wrote:
Dear Andy and All,
sorry for this long thread.
I am sure I was not able to put in practice some of your suggestions.
I put the full code here http://collabedit.com/wfhtq and reported below.
I tested it over the Q1 with the triple (?boss ex:isBossOf ?ind).
=========== BEFORE Q1:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
============= AFTER Q1:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ # Empty BGP
FILTER ( ?boss = "mathieu" )
}
}
But the filter is still there even if when I trace the execution it removes it.
I am doing the update between the AST and remove of the filter in
@Override
public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
Element elem = itr.next();
…
...
}
//With this code I am saying the following: make effective all the modifications that //have been made so far, if any.
if (arg0.getElements() == arg1)
{ return arg0; }
else {
ElementGroup el2 = new ElementGroup();
el2.getElements().addAll(arg1);
return el2;
}
}
What am I doing wrong?
Many Thanks for your help.
Best Regards,
Carlo
=== Code
//The main Class
public class RemoveTriple {
public RemoveTriple(){
super();
}
public Query removeTP(Query q, Triple tp) {
RemoveOpTransform rOpTransform = new RemoveOpTransform(q,tp);
Query queryWithoutTriplePattern = QueryTransformOps.transform(q, rOpTransform) ;
return queryWithoutTriplePattern;
}
}
// The current implementation of the RemoveOpTransform class. The class that implements the removal of the triple
public class RemoveOpTransform implements ElementTransform {
private Query query;
private Triple triple;
public RemoveOpTransform(Query q, Triple tp) {
this.query = q;
this.triple = tp;
}
@Override
public Element transform(ElementTriplesBlock arg0) {
System.out.println("[RemoveOpTransform::transform(ElementTriplesBlock arg0)] " + arg0.toString());
System.out.println("");
return arg0;
}
// This is the code related to the
@Override
public Element transform(ElementPathBlock eltPB) {
if (eltPB.isEmpty()) {
return eltPB;
}
Iterator<TriplePath> l = eltPB.patternElts();
while (l.hasNext()) {
TriplePath tp = l.next();
if (tp.asTriple().matches(this.triple)) {
l.remove();
return this.transform(eltPB);//eltPB;
}
}
return eltPB;
}
@Override
public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
Element elem = itr.next();
// I should go one by one the and examinate all the possible cases. For example:
//UNNION
if (elem instanceof ElementUnion) {
if (isUnionBothSidesEmpty) {
itr.remove();
}
}
//OPTION
if (elem instanceof ElementOptional) {
boolean isElementOptionalEmpty = isElementOptionalEmpty((ElementOptional) elem);
if (isElementOptionalEmpty) {
itr.remove();
// ElementGroup el2 = new ElementGroup();
// el2.getElements().addAll(arg1);
// return el2;
}
}
//ELEMENTGROUP
if (elem instanceof ElementGroup) {
boolean isElementGroupEmpty = isElementGroupEmpty((ElementGroup) elem);
if (isElementGroupEmpty) {
itr.remove();
// ElementGroup el2 = new ElementGroup();
// el2.getElements().addAll(arg1);
// return el2;
}
}
//FILTER
if (elem instanceof ElementFilter) {
//... check if this filter is the one that we should remove
//...get the variables of the triple pattern that we want to delete
Set<Var> tpVars = new HashSet();
Node subj = this.triple.getSubject();
if (subj.isVariable()) {
tpVars.add((Var) subj);
}
Node pred = this.triple.getPredicate();
if (pred.isVariable()) {
tpVars.add((Var) pred);
}
Node obj = this.triple.getObject();
if (obj.isVariable()) {
tpVars.add((Var) obj);
}
//...get the variables of the FILTER expression
Set<Var> expVars = ((ElementFilter) elem).getExpr().getVarsMentioned();
//...check whether the FILTER expression contains any of the triple pattern variable
for (Var var : expVars) {
//...if it does then we can delete the entire FILTER expression
if (tpVars.contains(var)) {
itr.remove();
break;
}
}
}
}// End of While
//With this code I am saying the following: make effective all the modifications that
//have been made so far, if any.
if (arg0.getElements() == arg1) {
return arg0;
} else {
ElementGroup el2 = new ElementGroup();
el2.getElements().addAll(arg1);
return el2;
}
}
@Override
public Element transform(ElementFilter arg0, Expr arg1) {
return arg0;
}
@Override
public Element transform(ElementAssign arg0, Var arg1, Expr arg2) {
return arg0;
}
@Override
public Element transform(ElementBind arg0, Var arg1, Expr arg2) {
System.out.println("[RemoveOpTransform::transform(ElementBind arg0)] " + arg0.toString());
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementData arg0) {
System.out.println("[RemoveOpTransform::transform(ElementData arg0)] " + arg0.toString());
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementDataset arg0, Element arg1) {
System.out.println("[RemoveOpTransform::transform(ElementDataset arg0)] " + arg0.toString());
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementUnion arg0, List<Element> arg1) {
System.out.println("[RemoveOpTransform::transform(ElementUnion arg0)] arg0 " + arg0.toString());
System.out.println("[RemoveOpTransform::transform(ElementUnion arg0)] arg1 " + arg1.toString());
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementOptional arg0, Element arg1) {
return arg0;
}
@Override
public Element transform(ElementNamedGraph arg0, Node arg1, Element arg2) {
System.out.println("[RemoveOpTransform::transform(ElementNamedGraph arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementExists arg0, Element arg1) {
System.out.println("[RemoveOpTransform::transform(ElementExists arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementNotExists arg0, Element arg1) {
System.out.println("[RemoveOpTransform::transform(ElementNotExists arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementMinus arg0, Element arg1) {
System.out.println("[RemoveOpTransform::transform(ElementMinus arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementService arg0, Node arg1, Element arg2) {
System.out.println("[RemoveOpTransform::transform(ElementService arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementSubQuery arg0, Query arg1) {
System.out.println("[RemoveOpTransform::transform(ElementSubQuery arg0)] ");
System.out.println("");
return arg0;
}
private boolean isUnionBothSidesEmpty1(ElementUnion elementUnion) {
List<Element> elemListUnion = elementUnion.getElements();//.getElements();
if (elemListUnion.size() == 2) {
Element left = elemListUnion.get(0);
Element right = elemListUnion.get(1);
if (left instanceof ElementGroup && right instanceof ElementGroup) {
if ((((ElementGroup) left).getElements().size() == 1) && (((ElementGroup) right).getElements().size() == 1)) {
Element elLeft = ((ElementGroup) left).getElements().get(0);
Element elRight = ((ElementGroup) right).getElements().get(0);
if ((elLeft instanceof ElementPathBlock) && (elRight instanceof ElementPathBlock)) {
ElementPathBlock epbLeft = (ElementPathBlock) elLeft;
ElementPathBlock epbRight = (ElementPathBlock) elRight;
if (epbLeft.isEmpty() && epbRight.isEmpty()) {
return true;
}
}
}
}
}
return false;
}
private boolean isElementGroupEmpty(ElementGroup elementGroup) {
List<Element> elList = ((ElementGroup) elementGroup).getElements();
if (elList.size() == 1) {
Element el = (Element) elList.get(0);
if (el instanceof ElementPathBlock) {
ElementPathBlock tmp = (ElementPathBlock) el;
if (tmp.isEmpty()) {
return true;
}
}
}
return false;
}
private boolean isElementOptionalEmpty(ElementOptional elementOptional) {
Element elm = ((ElementOptional) elementOptional).getOptionalElement();//.getElements();
if (elm instanceof ElementGroup) {
List<Element> elList = ((ElementGroup) elm).getElements();
if (elList.size() == 1) {
Element el = (Element) elList.get(0);
if (el instanceof ElementPathBlock) {
ElementPathBlock tmp = (ElementPathBlock) el;
if (tmp.isEmpty()) {
return true;
}
}
}
}
return false;
}
}
On 3 Feb 2016, at 00:00, Carlo.Allocca <ca...@open.ac.uk>> wrote:
Dear Andy and Paul,
some comments follow in lines.
On 2 Feb 2016, at 22:33, Andy Seaborne <an...@apache.org>> wrote:
On 02/02/16 19:29, Paul Houle wrote:
Carlo, Andy,
I like the Iterator<> interfaces in the Jena framework for getting data
out, but I make a habit of always putting results in a List or Queue or
something before putting them back into the same Jena model because i get
less BS per mile that way in terms of Exceptions and other exceptional
events.
Does Jena have an official policy on being reenterable in that way?
Carlo's issues are nothing to do with iterator policy.
Carlo - Use arg1 else you will not see your changes so far.
In
public Element transform(ElementGroup arg0, List<Element> arg1)
arg0 is the element from the AST before modification and
arg1 is the new elements to go in after modification by lower levels of the bottom-up rewrite.
So if you rewrite a ElementFilter by making a new one, it will appear in arg1 not in arg0.
I see. Thank you. Based on this, I am going to use "Iterator<Element> itr = arg1.iterator(); when implementing
public Element transform(ElementGroup arg0, List<Element> arg1).
Do not modify the Element* arguments in place.
See ElementTransformCopyBase
The default implementation is:
@Override
public Element transform(ElementGroup el, List<Element> elts) {
if ( el.getElements() == elts )
return el ;
ElementGroup el2 = new ElementGroup() ;
el2.getElements().addAll(elts) ;
return el2 ;
}
i.e if any change, detected by being not the exact identical list, then do a copy of the structure. This saves object churn.
I am going to change my implementation in such a way include all the above suggestions and clarifications.
Many Thanks for your willingness.
Best Regards,
Carlo.
Andy
On Tue, Feb 2, 2016 at 2:13 PM, Carlo.Allocca <ca...@open.ac.uk>>
wrote:
Dear Andy and All,
while I was extending and testing the code that I wrote so far concerning
the removing a triple from a given SPARQL query,
I realised that I get different outputs depending on how I start the
implementation of the public Element transform(ElementGroup arg0,
List<Element> arg1).
In particular, if I start with (1) I obtain some results, if I start with
(2) I obtain something different (you can see below the details).
I have also used ElementTransformCleanGroupsOfOne when ElementGroup is
empty
ElementTransform transform = new
ElementTransformCleanGroupsOfOne();
Element el2 = ElementTransformer.transform(eg, transform);
return el2;
but no difference in results. I am sure I am doing something wrong.
Moreover, my questions are: what is the main difference between the two
approaches? and when I should use ElementGroup arg0 and when List<Element>
arg1?
(1) public Element transform(ElementGroup arg0, List<Element> arg1) {
List<Element> elemList = arg0.getElements();
Iterator<Element> itr = elemList.iterator();
while (itr.hasNext()) {
}
…
…
}
(2) public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
}
…
…
}
I know that it may be related to the little knowledge about Jena.
Many Thanks in advice for your clarification on the above.
Best Regards,
Carlo
=======
Below, I reported the used code (at very bottom), the two used scenario
with test-cases and results. In practice, you can notice that:
==== TESTING:
Scenario A:
public Element transform(ElementGroup arg0, List<Element> arg1) {
List<Element> elemList = arg0.getElements();
Iterator<Element> itr = elemList.iterator();
while (itr.hasNext()) {
}
…
…
}
Test 1:
The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
=========== BEFORE Q1
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name
OPTIONAL
{ ?x foaf:mbox ?mbox }
}
============= AFTER Q1
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name }
Test2:
The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
query Q2:
=========== BEFORE Q2
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z
OPTIONAL
{ ?boss1 ex:isBossOf1 ?ind }
}
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
============= AFTER Q2: it does not remove the triple.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
Q3:
=========== BEFORE Q3:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ ?ind rdf:type ?z
FILTER ( ?ind = "mathieu" )
}
============= AFTER Q3: There is still an empty BGP present.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ # Empty BGP
}
Scenario B:
public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
}
…
…
}
Test 1:
The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
=========== BEFORE Q1
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name
OPTIONAL
{ ?x foaf:mbox ?mbox }
}
============= AFTER Q1: there is still the OPTION (with a ElementGroup
empty) clause.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name
OPTIONAL
{ # Empty BGP
}
}
Test 2:
The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
query Q2:
=========== BEFORE Q2
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z
OPTIONAL
{ ?boss1 ex:isBossOf1 ?ind }
}
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
============= AFTER Q2: it does not remove the OPTION and it leaves an
empty BGP.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z
OPTIONAL
{ # Empty BGP
}
}
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
Q3:
=========== BEFORE Q3
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ ?ind rdf:type ?z
FILTER ( ?ind = "mathieu" )
}
============= AFTER Q3: It does not remove the FILTER, but just the triple.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ # Empty BGP
FILTER ( ?boss = "mathieu" )
}
}
=== FULL CODE used with public Element transform(ElementPathBlock
eltPB)
@Override
public Element transform(ElementPathBlock eltPB) {
if (eltPB.isEmpty()) {
//System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
ElementPathBlock IS EMPTY:: " + eltPB.toString());
return eltPB;
}
System.out.println("[RemoveOpTransform::transform(ElementPathBlock
arg0)] ElementPathBlock:: " + eltPB.toString());
Iterator<TriplePath> l = eltPB.patternElts();
while (l.hasNext()) {
TriplePath tp = l.next();
if (tp.asTriple().matches(this.triple)) {
l.remove();
System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
ElementPathBlock:: " + tp.toString() + " TRIPLE JUST REMOVED!!!");
//System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
TRIPLE JUST REMOVED!!! ");
System.out.println("");
return this.transform(eltPB);//eltPB;
}
}
return eltPB;
}
=== FULL CODE used with public Element transform(ElementGroup arg0,
List<Element> arg1)
@Override
public Element transform(ElementGroup arg0, List<Element> arg1) {
List<Element> elemList = arg0.getElements();
Iterator<Element> itr = elemList.iterator();
//Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
Element elem = itr.next();
if (elem instanceof ElementOptional) {
boolean isElementOptionalEmpty =
isElementOptionalEmpty((ElementOptional) elem);
if (isElementOptionalEmpty) {
itr.remove();
}
}
else if (elem instanceof ElementGroup) {
boolean isElementGroupEmpty =
isElementGroupEmpty((ElementGroup) elem);
if (isElementGroupEmpty) {
itr.remove();
}
}
else if (elem instanceof ElementFilter) {
//... check if this filter is the one that we should remove
//...get the variables of the triple pattern that we want
to delete
Set<Var> tpVars = new HashSet();
Node subj = this.triple.getSubject();
if (subj.isVariable()) {
tpVars.add((Var) subj);
}
Node pred = this.triple.getPredicate();
if (pred.isVariable()) {
tpVars.add((Var) pred);
}
Node obj = this.triple.getObject();
if (obj.isVariable()) {
tpVars.add((Var) obj);
}
//...get the variables of the FILTER expression
Set<Var> expVars = ((ElementFilter)
elem).getExpr().getVarsMentioned();
//...check whether the FILTER expression contains any of
the triple pattern variable
for (Var var : expVars) {
//..if it does then we have to delete the entire
FILTER expression
if (tpVars.contains(var)) {
itr.remove();
}
}
}
else if (elem instanceof ElementUnion) {
boolean isUnionBothSidesEmpty =
isUnionBothSidesEmpty1((ElementUnion) elem);
if (isUnionBothSidesEmpty) {
itr.remove();
}
}
}
return arg0;
}
On 2 Feb 2016, at 10:54, Carlo.Allocca <ca...@open.ac.uk><mailto:
carlo.allocca@open.ac.uk<ma...@open.ac.uk>>> wrote:
Dear Andy,
Thank you for your time. Very appreciated.
Some comments follow in lines.
On 2 Feb 2016, at 09:36, Andy Seaborne <an...@apache.org><mailto:
andy@apache.org<ma...@apache.org>>> wrote:
when removing the triple (?boss ex:isBossOf ?ind .”), I get
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ # Empty BGP
}
}
}
which is OK.
I just need to find out how to remove an ElementGroup which contains only
one element which is the EMPTY one.
Of course, I need to do the same for the other case, e.g. OPTION,
SUBquery, etc.
Do note that evaluating {} (empty syntax group) yields one row of zero
columns - it contributes to the overall results (it's the join identity).
I see. To avoid this I am going to apply a
ElementTransformCleanGroupsOfOne as you suggested.
Now you have to look at all the elements that have a group in
ElementUnion, ElementOptional, ElementMinus, …
Yes, I need to cover all the SPARQL language from the “public Element
transform(ElementGroup arg0, List<Element> arg1)” call.
At least this is my understanding so far.
That is what ElementTransformCleanGroupsOfOne does, except it looks for
"groups of one"
.. UNION { { stuff } }
and isn't to fussy about finding them all (it's an optimization, more a
tidying of the tree, not a change in the effect of a query which is what
removing triple patterns is).
And of course changes from the bottom could potentially cause change all
the way up to the top of the syntax tree.
also: they maybe be original, legal empty groups in the tree.
Thanks for the detailed clarifications. Indeed, I will consider them.
Many Thanks,
Best Regards,
Carlo
Andy
-- The Open University is incorporated by Royal Charter (RC 000391), an
exempt charity in England & Wales and a charity registered in Scotland (SC
038302). The Open University is authorised and regulated by the Financial
Conduct Authority.
-- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
Re: How to remove consistently a triple pattern given a SPARQL query?
Posted by Andy Seaborne <an...@apache.org>.
On 04/02/16 19:27, Carlo.Allocca wrote:
> Dear Andy and All,
>
> Thank you very much for all your suggestions and willingness.
>
> I went through all of them again and, assembling them (changing a bit the code reported in the previous email)
> I got a reasonable first version that is working. But I had to use arg0 instead of arg1 as suggested.
This will get you into trouble!
It probably means something somewhere below is modifying the input
structure, not taking a copy.
>
> Please, could I ask the followings:
>
> Is there any way to access the aggregate expressions (e.g. GROUP BY or HAVING ) when applying an implementation of ElementTransform?
Look at QueryTransformOps.transform(Query query, ..) which applies
transaforms to the thigns that attach to the query object itseld like GROUP.
>
> The reason of such a question is: when applying the operation remove of the triple (?x2 foaf:mbox2 ?mbox2 .) over Q1,
> it would make sense to eliminate ORDER BY too as it contains a variable (?x2) from the triple that was eliminated and there no other triple containing such a variable.
>
> Q1:
>
> String qString8 =
> SELECT DISTINCT ?x2 ?mbox2 where "
> {
> ?x foaf:name ?name .
> ?x2 foaf:mbox2 ?mbox2 .
> }
> ORDER BY ?x2
>
>
> Many Thanks in advance.
> Best Regards,
> Carlo
>
>
>
>
> On 3 Feb 2016, at 14:55, Carlo.Allocca <ca...@open.ac.uk>> wrote:
>
> Dear Andy and All,
>
> sorry for this long thread.
> I am sure I was not able to put in practice some of your suggestions.
>
> I put the full code here http://collabedit.com/wfhtq and reported below.
>
> I tested it over the Q1 with the triple (?boss ex:isBossOf ?ind).
>
> =========== BEFORE Q1:
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
>
>
>
> ============= AFTER Q1:
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { # Empty BGP
>
> FILTER ( ?boss = "mathieu" )
> }
> }
>
>
> But the filter is still there even if when I trace the execution it removes it.
> I am doing the update between the AST and remove of the filter in
>
> @Override
> public Element transform(ElementGroup arg0, List<Element> arg1) {
> Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
> Element elem = itr.next();
> …
> ...
> }
>
> //With this code I am saying the following: make effective all the modifications that //have been made so far, if any.
> if (arg0.getElements() == arg1)
> { return arg0; }
> else {
> ElementGroup el2 = new ElementGroup();
> el2.getElements().addAll(arg1);
> return el2;
> }
>
> }
>
>
> What am I doing wrong?
>
> Many Thanks for your help.
>
> Best Regards,
> Carlo
>
>
>
>
>
> === Code
>
> //The main Class
>
> public class RemoveTriple {
>
> public RemoveTriple(){
> super();
> }
>
> public Query removeTP(Query q, Triple tp) {
> RemoveOpTransform rOpTransform = new RemoveOpTransform(q,tp);
> Query queryWithoutTriplePattern = QueryTransformOps.transform(q, rOpTransform) ;
> return queryWithoutTriplePattern;
> }
> }
>
> // The current implementation of the RemoveOpTransform class. The class that implements the removal of the triple
>
> public class RemoveOpTransform implements ElementTransform {
>
> private Query query;
> private Triple triple;
>
> public RemoveOpTransform(Query q, Triple tp) {
> this.query = q;
> this.triple = tp;
> }
>
> @Override
> public Element transform(ElementTriplesBlock arg0) {
> System.out.println("[RemoveOpTransform::transform(ElementTriplesBlock arg0)] " + arg0.toString());
> System.out.println("");
> return arg0;
> }
>
> // This is the code related to the
> @Override
> public Element transform(ElementPathBlock eltPB) {
> if (eltPB.isEmpty()) {
> return eltPB;
> }
> Iterator<TriplePath> l = eltPB.patternElts();
> while (l.hasNext()) {
> TriplePath tp = l.next();
> if (tp.asTriple().matches(this.triple)) {
> l.remove();
> return this.transform(eltPB);//eltPB;
> }
> }
> return eltPB;
> }
>
>
> @Override
> public Element transform(ElementGroup arg0, List<Element> arg1) {
>
> Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
> Element elem = itr.next();
> // I should go one by one the and examinate all the possible cases. For example:
>
> //UNNION
> if (elem instanceof ElementUnion) {
> if (isUnionBothSidesEmpty) {
> itr.remove();
> }
> }
>
> //OPTION
> if (elem instanceof ElementOptional) {
> boolean isElementOptionalEmpty = isElementOptionalEmpty((ElementOptional) elem);
> if (isElementOptionalEmpty) {
> itr.remove();
> // ElementGroup el2 = new ElementGroup();
> // el2.getElements().addAll(arg1);
> // return el2;
> }
> }
>
> //ELEMENTGROUP
> if (elem instanceof ElementGroup) {
> boolean isElementGroupEmpty = isElementGroupEmpty((ElementGroup) elem);
> if (isElementGroupEmpty) {
> itr.remove();
> // ElementGroup el2 = new ElementGroup();
> // el2.getElements().addAll(arg1);
> // return el2;
> }
> }
>
> //FILTER
> if (elem instanceof ElementFilter) {
> //... check if this filter is the one that we should remove
> //...get the variables of the triple pattern that we want to delete
> Set<Var> tpVars = new HashSet();
> Node subj = this.triple.getSubject();
> if (subj.isVariable()) {
> tpVars.add((Var) subj);
> }
> Node pred = this.triple.getPredicate();
> if (pred.isVariable()) {
> tpVars.add((Var) pred);
> }
> Node obj = this.triple.getObject();
> if (obj.isVariable()) {
> tpVars.add((Var) obj);
> }
> //...get the variables of the FILTER expression
> Set<Var> expVars = ((ElementFilter) elem).getExpr().getVarsMentioned();
> //...check whether the FILTER expression contains any of the triple pattern variable
> for (Var var : expVars) {
> //...if it does then we can delete the entire FILTER expression
> if (tpVars.contains(var)) {
> itr.remove();
> break;
> }
> }
> }
>
> }// End of While
>
> //With this code I am saying the following: make effective all the modifications that
> //have been made so far, if any.
> if (arg0.getElements() == arg1) {
> return arg0;
> } else {
> ElementGroup el2 = new ElementGroup();
> el2.getElements().addAll(arg1);
> return el2;
> }
> }
>
>
>
>
> @Override
> public Element transform(ElementFilter arg0, Expr arg1) {
> return arg0;
> }
>
> @Override
> public Element transform(ElementAssign arg0, Var arg1, Expr arg2) {
> return arg0;
> }
>
> @Override
> public Element transform(ElementBind arg0, Var arg1, Expr arg2) {
> System.out.println("[RemoveOpTransform::transform(ElementBind arg0)] " + arg0.toString());
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementData arg0) {
> System.out.println("[RemoveOpTransform::transform(ElementData arg0)] " + arg0.toString());
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementDataset arg0, Element arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementDataset arg0)] " + arg0.toString());
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementUnion arg0, List<Element> arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementUnion arg0)] arg0 " + arg0.toString());
> System.out.println("[RemoveOpTransform::transform(ElementUnion arg0)] arg1 " + arg1.toString());
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementOptional arg0, Element arg1) {
> return arg0;
> }
>
> @Override
> public Element transform(ElementNamedGraph arg0, Node arg1, Element arg2) {
> System.out.println("[RemoveOpTransform::transform(ElementNamedGraph arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementExists arg0, Element arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementExists arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementNotExists arg0, Element arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementNotExists arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementMinus arg0, Element arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementMinus arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementService arg0, Node arg1, Element arg2) {
> System.out.println("[RemoveOpTransform::transform(ElementService arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> @Override
> public Element transform(ElementSubQuery arg0, Query arg1) {
> System.out.println("[RemoveOpTransform::transform(ElementSubQuery arg0)] ");
> System.out.println("");
> return arg0;
> }
>
> private boolean isUnionBothSidesEmpty1(ElementUnion elementUnion) {
> List<Element> elemListUnion = elementUnion.getElements();//.getElements();
> if (elemListUnion.size() == 2) {
> Element left = elemListUnion.get(0);
> Element right = elemListUnion.get(1);
> if (left instanceof ElementGroup && right instanceof ElementGroup) {
> if ((((ElementGroup) left).getElements().size() == 1) && (((ElementGroup) right).getElements().size() == 1)) {
> Element elLeft = ((ElementGroup) left).getElements().get(0);
> Element elRight = ((ElementGroup) right).getElements().get(0);
> if ((elLeft instanceof ElementPathBlock) && (elRight instanceof ElementPathBlock)) {
> ElementPathBlock epbLeft = (ElementPathBlock) elLeft;
> ElementPathBlock epbRight = (ElementPathBlock) elRight;
> if (epbLeft.isEmpty() && epbRight.isEmpty()) {
> return true;
> }
> }
> }
> }
> }
> return false;
> }
>
> private boolean isElementGroupEmpty(ElementGroup elementGroup) {
> List<Element> elList = ((ElementGroup) elementGroup).getElements();
> if (elList.size() == 1) {
> Element el = (Element) elList.get(0);
> if (el instanceof ElementPathBlock) {
> ElementPathBlock tmp = (ElementPathBlock) el;
> if (tmp.isEmpty()) {
> return true;
> }
> }
> }
> return false;
> }
>
> private boolean isElementOptionalEmpty(ElementOptional elementOptional) {
> Element elm = ((ElementOptional) elementOptional).getOptionalElement();//.getElements();
> if (elm instanceof ElementGroup) {
> List<Element> elList = ((ElementGroup) elm).getElements();
> if (elList.size() == 1) {
> Element el = (Element) elList.get(0);
> if (el instanceof ElementPathBlock) {
> ElementPathBlock tmp = (ElementPathBlock) el;
> if (tmp.isEmpty()) {
> return true;
> }
> }
> }
> }
> return false;
> }
>
> }
>
>
>
>
>
>
>
>
> On 3 Feb 2016, at 00:00, Carlo.Allocca <ca...@open.ac.uk>> wrote:
>
> Dear Andy and Paul,
>
> some comments follow in lines.
>
> On 2 Feb 2016, at 22:33, Andy Seaborne <an...@apache.org>> wrote:
>
> On 02/02/16 19:29, Paul Houle wrote:
> Carlo, Andy,
>
> I like the Iterator<> interfaces in the Jena framework for getting data
> out, but I make a habit of always putting results in a List or Queue or
> something before putting them back into the same Jena model because i get
> less BS per mile that way in terms of Exceptions and other exceptional
> events.
>
> Does Jena have an official policy on being reenterable in that way?
>
> Carlo's issues are nothing to do with iterator policy.
>
> Carlo - Use arg1 else you will not see your changes so far.
>
> In
>
> public Element transform(ElementGroup arg0, List<Element> arg1)
>
> arg0 is the element from the AST before modification and
> arg1 is the new elements to go in after modification by lower levels of the bottom-up rewrite.
>
>
> So if you rewrite a ElementFilter by making a new one, it will appear in arg1 not in arg0.
> I see. Thank you. Based on this, I am going to use "Iterator<Element> itr = arg1.iterator(); when implementing
> public Element transform(ElementGroup arg0, List<Element> arg1).
>
>
>
> Do not modify the Element* arguments in place.
>
>
> See ElementTransformCopyBase
>
> The default implementation is:
>
> @Override
> public Element transform(ElementGroup el, List<Element> elts) {
> if ( el.getElements() == elts )
> return el ;
> ElementGroup el2 = new ElementGroup() ;
> el2.getElements().addAll(elts) ;
> return el2 ;
> }
>
>
> i.e if any change, detected by being not the exact identical list, then do a copy of the structure. This saves object churn.
>
> I am going to change my implementation in such a way include all the above suggestions and clarifications.
>
> Many Thanks for your willingness.
> Best Regards,
> Carlo.
>
>
> Andy
>
>
> On Tue, Feb 2, 2016 at 2:13 PM, Carlo.Allocca <ca...@open.ac.uk>>
> wrote:
>
>
> Dear Andy and All,
>
> while I was extending and testing the code that I wrote so far concerning
> the removing a triple from a given SPARQL query,
> I realised that I get different outputs depending on how I start the
> implementation of the public Element transform(ElementGroup arg0,
> List<Element> arg1).
> In particular, if I start with (1) I obtain some results, if I start with
> (2) I obtain something different (you can see below the details).
>
> I have also used ElementTransformCleanGroupsOfOne when ElementGroup is
> empty
> ElementTransform transform = new
> ElementTransformCleanGroupsOfOne();
> Element el2 = ElementTransformer.transform(eg, transform);
> return el2;
>
> but no difference in results. I am sure I am doing something wrong.
> Moreover, my questions are: what is the main difference between the two
> approaches? and when I should use ElementGroup arg0 and when List<Element>
> arg1?
>
>
> (1) public Element transform(ElementGroup arg0, List<Element> arg1) {
> List<Element> elemList = arg0.getElements();
> Iterator<Element> itr = elemList.iterator();
> while (itr.hasNext()) {
>
>
> }
> …
> …
> }
>
>
> (2) public Element transform(ElementGroup arg0, List<Element> arg1) {
>
>
>
> Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
>
>
> }
> …
> …
> }
>
> I know that it may be related to the little knowledge about Jena.
> Many Thanks in advice for your clarification on the above.
>
> Best Regards,
> Carlo
>
>
> =======
>
> Below, I reported the used code (at very bottom), the two used scenario
> with test-cases and results. In practice, you can notice that:
>
>
>
> ==== TESTING:
>
> Scenario A:
>
> public Element transform(ElementGroup arg0, List<Element> arg1) {
>
>
>
> List<Element> elemList = arg0.getElements();
> Iterator<Element> itr = elemList.iterator();
> while (itr.hasNext()) {
>
>
> }
> …
> …
> }
>
>
> Test 1:
>
> The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
>
> =========== BEFORE Q1
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>
> SELECT DISTINCT ?name ?mbox
> WHERE
> { ?x foaf:name ?name
> OPTIONAL
> { ?x foaf:mbox ?mbox }
> }
>
>
> ============= AFTER Q1
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>
> SELECT DISTINCT ?name ?mbox
> WHERE
> { ?x foaf:name ?name }
>
>
> Test2:
>
> The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
> query Q2:
>
>
>
> =========== BEFORE Q2
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z
> OPTIONAL
> { ?boss1 ex:isBossOf1 ?ind }
> }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
> }
>
> ============= AFTER Q2: it does not remove the triple.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
> }
>
>
> Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
> Q3:
>
> =========== BEFORE Q3:
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { ?ind rdf:type ?z
> FILTER ( ?ind = "mathieu" )
> }
>
> ============= AFTER Q3: There is still an empty BGP present.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { # Empty BGP
>
>
>
> }
>
>
>
>
>
>
>
>
> Scenario B:
>
> public Element transform(ElementGroup arg0, List<Element> arg1) {
>
>
>
> Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
>
>
> }
> …
> …
> }
>
>
> Test 1:
>
> The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
>
> =========== BEFORE Q1
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>
> SELECT DISTINCT ?name ?mbox
> WHERE
> { ?x foaf:name ?name
> OPTIONAL
> { ?x foaf:mbox ?mbox }
> }
>
>
> ============= AFTER Q1: there is still the OPTION (with a ElementGroup
> empty) clause.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>
> SELECT DISTINCT ?name ?mbox
> WHERE
> { ?x foaf:name ?name
> OPTIONAL
> { # Empty BGP
>
>
>
> }
> }
>
>
>
>
> Test 2:
>
> The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
> query Q2:
>
>
>
> =========== BEFORE Q2
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z
> OPTIONAL
> { ?boss1 ex:isBossOf1 ?ind }
> }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
> }
>
> ============= AFTER Q2: it does not remove the OPTION and it leaves an
> empty BGP.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z
> OPTIONAL
> { # Empty BGP
>
>
>
> }
> }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
> }
>
> Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
> Q3:
>
> =========== BEFORE Q3
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { ?ind rdf:type ?z
> FILTER ( ?ind = "mathieu" )
> }
>
> ============= AFTER Q3: It does not remove the FILTER, but just the triple.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { # Empty BGP
>
>
>
> FILTER ( ?boss = "mathieu" )
> }
> }
>
>
>
>
>
>
>
> === FULL CODE used with public Element transform(ElementPathBlock
> eltPB)
>
> @Override
> public Element transform(ElementPathBlock eltPB) {
> if (eltPB.isEmpty()) {
>
> //System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
> ElementPathBlock IS EMPTY:: " + eltPB.toString());
> return eltPB;
> }
> System.out.println("[RemoveOpTransform::transform(ElementPathBlock
> arg0)] ElementPathBlock:: " + eltPB.toString());
> Iterator<TriplePath> l = eltPB.patternElts();
> while (l.hasNext()) {
> TriplePath tp = l.next();
> if (tp.asTriple().matches(this.triple)) {
> l.remove();
>
> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
> ElementPathBlock:: " + tp.toString() + " TRIPLE JUST REMOVED!!!");
>
> //System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
> TRIPLE JUST REMOVED!!! ");
> System.out.println("");
> return this.transform(eltPB);//eltPB;
> }
> }
> return eltPB;
> }
>
>
> === FULL CODE used with public Element transform(ElementGroup arg0,
> List<Element> arg1)
>
> @Override
> public Element transform(ElementGroup arg0, List<Element> arg1) {
>
>
>
> List<Element> elemList = arg0.getElements();
> Iterator<Element> itr = elemList.iterator();
> //Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
> Element elem = itr.next();
> if (elem instanceof ElementOptional) {
> boolean isElementOptionalEmpty =
> isElementOptionalEmpty((ElementOptional) elem);
> if (isElementOptionalEmpty) {
> itr.remove();
> }
> }
>
> else if (elem instanceof ElementGroup) {
> boolean isElementGroupEmpty =
> isElementGroupEmpty((ElementGroup) elem);
> if (isElementGroupEmpty) {
> itr.remove();
> }
> }
> else if (elem instanceof ElementFilter) {
> //... check if this filter is the one that we should remove
> //...get the variables of the triple pattern that we want
> to delete
> Set<Var> tpVars = new HashSet();
> Node subj = this.triple.getSubject();
> if (subj.isVariable()) {
> tpVars.add((Var) subj);
> }
> Node pred = this.triple.getPredicate();
> if (pred.isVariable()) {
> tpVars.add((Var) pred);
> }
> Node obj = this.triple.getObject();
> if (obj.isVariable()) {
> tpVars.add((Var) obj);
> }
> //...get the variables of the FILTER expression
> Set<Var> expVars = ((ElementFilter)
> elem).getExpr().getVarsMentioned();
> //...check whether the FILTER expression contains any of
> the triple pattern variable
> for (Var var : expVars) {
> //..if it does then we have to delete the entire
> FILTER expression
> if (tpVars.contains(var)) {
> itr.remove();
> }
> }
> }
> else if (elem instanceof ElementUnion) {
> boolean isUnionBothSidesEmpty =
> isUnionBothSidesEmpty1((ElementUnion) elem);
> if (isUnionBothSidesEmpty) {
> itr.remove();
> }
> }
>
> }
> return arg0;
> }
>
>
>
>
>
>
>
>
> On 2 Feb 2016, at 10:54, Carlo.Allocca <ca...@open.ac.uk><mailto:
> carlo.allocca@open.ac.uk<ma...@open.ac.uk>>> wrote:
>
> Dear Andy,
>
> Thank you for your time. Very appreciated.
> Some comments follow in lines.
>
> On 2 Feb 2016, at 09:36, Andy Seaborne <an...@apache.org><mailto:
> andy@apache.org<ma...@apache.org>>> wrote:
>
>
> when removing the triple (?boss ex:isBossOf ?ind .”), I get
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { # Empty BGP
>
> }
> }
> }
>
> which is OK.
> I just need to find out how to remove an ElementGroup which contains only
> one element which is the EMPTY one.
> Of course, I need to do the same for the other case, e.g. OPTION,
> SUBquery, etc.
>
> Do note that evaluating {} (empty syntax group) yields one row of zero
> columns - it contributes to the overall results (it's the join identity).
>
> I see. To avoid this I am going to apply a
> ElementTransformCleanGroupsOfOne as you suggested.
>
>
> Now you have to look at all the elements that have a group in
> ElementUnion, ElementOptional, ElementMinus, …
> Yes, I need to cover all the SPARQL language from the “public Element
> transform(ElementGroup arg0, List<Element> arg1)” call.
> At least this is my understanding so far.
>
>
>
> That is what ElementTransformCleanGroupsOfOne does, except it looks for
> "groups of one"
>
> .. UNION { { stuff } }
>
> and isn't to fussy about finding them all (it's an optimization, more a
> tidying of the tree, not a change in the effect of a query which is what
> removing triple patterns is).
>
> And of course changes from the bottom could potentially cause change all
> the way up to the top of the syntax tree.
>
> also: they maybe be original, legal empty groups in the tree.
>
> Thanks for the detailed clarifications. Indeed, I will consider them.
>
> Many Thanks,
> Best Regards,
> Carlo
>
>
>
> Andy
>
>
>
>
>
>
> -- The Open University is incorporated by Royal Charter (RC 000391), an
> exempt charity in England & Wales and a charity registered in Scotland (SC
> 038302). The Open University is authorised and regulated by the Financial
> Conduct Authority.
>
>
>
>
>
>
> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Dear Andy and All,
Thank you very much for all your suggestions and willingness.
I went through all of them again and, assembling them (changing a bit the code reported in the previous email)
I got a reasonable first version that is working. But I had to use arg0 instead of arg1 as suggested.
Please, could I ask the followings:
Is there any way to access the aggregate expressions (e.g. GROUP BY or HAVING ) when applying an implementation of ElementTransform?
The reason of such a question is: when applying the operation remove of the triple (?x2 foaf:mbox2 ?mbox2 .) over Q1,
it would make sense to eliminate ORDER BY too as it contains a variable (?x2) from the triple that was eliminated and there no other triple containing such a variable.
Q1:
String qString8 =
SELECT DISTINCT ?x2 ?mbox2 where "
{
?x foaf:name ?name .
?x2 foaf:mbox2 ?mbox2 .
}
ORDER BY ?x2
Many Thanks in advance.
Best Regards,
Carlo
On 3 Feb 2016, at 14:55, Carlo.Allocca <ca...@open.ac.uk>> wrote:
Dear Andy and All,
sorry for this long thread.
I am sure I was not able to put in practice some of your suggestions.
I put the full code here http://collabedit.com/wfhtq and reported below.
I tested it over the Q1 with the triple (?boss ex:isBossOf ?ind).
=========== BEFORE Q1:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
============= AFTER Q1:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ # Empty BGP
FILTER ( ?boss = "mathieu" )
}
}
But the filter is still there even if when I trace the execution it removes it.
I am doing the update between the AST and remove of the filter in
@Override
public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
Element elem = itr.next();
…
...
}
//With this code I am saying the following: make effective all the modifications that //have been made so far, if any.
if (arg0.getElements() == arg1)
{ return arg0; }
else {
ElementGroup el2 = new ElementGroup();
el2.getElements().addAll(arg1);
return el2;
}
}
What am I doing wrong?
Many Thanks for your help.
Best Regards,
Carlo
=== Code
//The main Class
public class RemoveTriple {
public RemoveTriple(){
super();
}
public Query removeTP(Query q, Triple tp) {
RemoveOpTransform rOpTransform = new RemoveOpTransform(q,tp);
Query queryWithoutTriplePattern = QueryTransformOps.transform(q, rOpTransform) ;
return queryWithoutTriplePattern;
}
}
// The current implementation of the RemoveOpTransform class. The class that implements the removal of the triple
public class RemoveOpTransform implements ElementTransform {
private Query query;
private Triple triple;
public RemoveOpTransform(Query q, Triple tp) {
this.query = q;
this.triple = tp;
}
@Override
public Element transform(ElementTriplesBlock arg0) {
System.out.println("[RemoveOpTransform::transform(ElementTriplesBlock arg0)] " + arg0.toString());
System.out.println("");
return arg0;
}
// This is the code related to the
@Override
public Element transform(ElementPathBlock eltPB) {
if (eltPB.isEmpty()) {
return eltPB;
}
Iterator<TriplePath> l = eltPB.patternElts();
while (l.hasNext()) {
TriplePath tp = l.next();
if (tp.asTriple().matches(this.triple)) {
l.remove();
return this.transform(eltPB);//eltPB;
}
}
return eltPB;
}
@Override
public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
Element elem = itr.next();
// I should go one by one the and examinate all the possible cases. For example:
//UNNION
if (elem instanceof ElementUnion) {
if (isUnionBothSidesEmpty) {
itr.remove();
}
}
//OPTION
if (elem instanceof ElementOptional) {
boolean isElementOptionalEmpty = isElementOptionalEmpty((ElementOptional) elem);
if (isElementOptionalEmpty) {
itr.remove();
// ElementGroup el2 = new ElementGroup();
// el2.getElements().addAll(arg1);
// return el2;
}
}
//ELEMENTGROUP
if (elem instanceof ElementGroup) {
boolean isElementGroupEmpty = isElementGroupEmpty((ElementGroup) elem);
if (isElementGroupEmpty) {
itr.remove();
// ElementGroup el2 = new ElementGroup();
// el2.getElements().addAll(arg1);
// return el2;
}
}
//FILTER
if (elem instanceof ElementFilter) {
//... check if this filter is the one that we should remove
//...get the variables of the triple pattern that we want to delete
Set<Var> tpVars = new HashSet();
Node subj = this.triple.getSubject();
if (subj.isVariable()) {
tpVars.add((Var) subj);
}
Node pred = this.triple.getPredicate();
if (pred.isVariable()) {
tpVars.add((Var) pred);
}
Node obj = this.triple.getObject();
if (obj.isVariable()) {
tpVars.add((Var) obj);
}
//...get the variables of the FILTER expression
Set<Var> expVars = ((ElementFilter) elem).getExpr().getVarsMentioned();
//...check whether the FILTER expression contains any of the triple pattern variable
for (Var var : expVars) {
//...if it does then we can delete the entire FILTER expression
if (tpVars.contains(var)) {
itr.remove();
break;
}
}
}
}// End of While
//With this code I am saying the following: make effective all the modifications that
//have been made so far, if any.
if (arg0.getElements() == arg1) {
return arg0;
} else {
ElementGroup el2 = new ElementGroup();
el2.getElements().addAll(arg1);
return el2;
}
}
@Override
public Element transform(ElementFilter arg0, Expr arg1) {
return arg0;
}
@Override
public Element transform(ElementAssign arg0, Var arg1, Expr arg2) {
return arg0;
}
@Override
public Element transform(ElementBind arg0, Var arg1, Expr arg2) {
System.out.println("[RemoveOpTransform::transform(ElementBind arg0)] " + arg0.toString());
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementData arg0) {
System.out.println("[RemoveOpTransform::transform(ElementData arg0)] " + arg0.toString());
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementDataset arg0, Element arg1) {
System.out.println("[RemoveOpTransform::transform(ElementDataset arg0)] " + arg0.toString());
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementUnion arg0, List<Element> arg1) {
System.out.println("[RemoveOpTransform::transform(ElementUnion arg0)] arg0 " + arg0.toString());
System.out.println("[RemoveOpTransform::transform(ElementUnion arg0)] arg1 " + arg1.toString());
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementOptional arg0, Element arg1) {
return arg0;
}
@Override
public Element transform(ElementNamedGraph arg0, Node arg1, Element arg2) {
System.out.println("[RemoveOpTransform::transform(ElementNamedGraph arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementExists arg0, Element arg1) {
System.out.println("[RemoveOpTransform::transform(ElementExists arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementNotExists arg0, Element arg1) {
System.out.println("[RemoveOpTransform::transform(ElementNotExists arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementMinus arg0, Element arg1) {
System.out.println("[RemoveOpTransform::transform(ElementMinus arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementService arg0, Node arg1, Element arg2) {
System.out.println("[RemoveOpTransform::transform(ElementService arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementSubQuery arg0, Query arg1) {
System.out.println("[RemoveOpTransform::transform(ElementSubQuery arg0)] ");
System.out.println("");
return arg0;
}
private boolean isUnionBothSidesEmpty1(ElementUnion elementUnion) {
List<Element> elemListUnion = elementUnion.getElements();//.getElements();
if (elemListUnion.size() == 2) {
Element left = elemListUnion.get(0);
Element right = elemListUnion.get(1);
if (left instanceof ElementGroup && right instanceof ElementGroup) {
if ((((ElementGroup) left).getElements().size() == 1) && (((ElementGroup) right).getElements().size() == 1)) {
Element elLeft = ((ElementGroup) left).getElements().get(0);
Element elRight = ((ElementGroup) right).getElements().get(0);
if ((elLeft instanceof ElementPathBlock) && (elRight instanceof ElementPathBlock)) {
ElementPathBlock epbLeft = (ElementPathBlock) elLeft;
ElementPathBlock epbRight = (ElementPathBlock) elRight;
if (epbLeft.isEmpty() && epbRight.isEmpty()) {
return true;
}
}
}
}
}
return false;
}
private boolean isElementGroupEmpty(ElementGroup elementGroup) {
List<Element> elList = ((ElementGroup) elementGroup).getElements();
if (elList.size() == 1) {
Element el = (Element) elList.get(0);
if (el instanceof ElementPathBlock) {
ElementPathBlock tmp = (ElementPathBlock) el;
if (tmp.isEmpty()) {
return true;
}
}
}
return false;
}
private boolean isElementOptionalEmpty(ElementOptional elementOptional) {
Element elm = ((ElementOptional) elementOptional).getOptionalElement();//.getElements();
if (elm instanceof ElementGroup) {
List<Element> elList = ((ElementGroup) elm).getElements();
if (elList.size() == 1) {
Element el = (Element) elList.get(0);
if (el instanceof ElementPathBlock) {
ElementPathBlock tmp = (ElementPathBlock) el;
if (tmp.isEmpty()) {
return true;
}
}
}
}
return false;
}
}
On 3 Feb 2016, at 00:00, Carlo.Allocca <ca...@open.ac.uk>> wrote:
Dear Andy and Paul,
some comments follow in lines.
On 2 Feb 2016, at 22:33, Andy Seaborne <an...@apache.org>> wrote:
On 02/02/16 19:29, Paul Houle wrote:
Carlo, Andy,
I like the Iterator<> interfaces in the Jena framework for getting data
out, but I make a habit of always putting results in a List or Queue or
something before putting them back into the same Jena model because i get
less BS per mile that way in terms of Exceptions and other exceptional
events.
Does Jena have an official policy on being reenterable in that way?
Carlo's issues are nothing to do with iterator policy.
Carlo - Use arg1 else you will not see your changes so far.
In
public Element transform(ElementGroup arg0, List<Element> arg1)
arg0 is the element from the AST before modification and
arg1 is the new elements to go in after modification by lower levels of the bottom-up rewrite.
So if you rewrite a ElementFilter by making a new one, it will appear in arg1 not in arg0.
I see. Thank you. Based on this, I am going to use "Iterator<Element> itr = arg1.iterator(); when implementing
public Element transform(ElementGroup arg0, List<Element> arg1).
Do not modify the Element* arguments in place.
See ElementTransformCopyBase
The default implementation is:
@Override
public Element transform(ElementGroup el, List<Element> elts) {
if ( el.getElements() == elts )
return el ;
ElementGroup el2 = new ElementGroup() ;
el2.getElements().addAll(elts) ;
return el2 ;
}
i.e if any change, detected by being not the exact identical list, then do a copy of the structure. This saves object churn.
I am going to change my implementation in such a way include all the above suggestions and clarifications.
Many Thanks for your willingness.
Best Regards,
Carlo.
Andy
On Tue, Feb 2, 2016 at 2:13 PM, Carlo.Allocca <ca...@open.ac.uk>>
wrote:
Dear Andy and All,
while I was extending and testing the code that I wrote so far concerning
the removing a triple from a given SPARQL query,
I realised that I get different outputs depending on how I start the
implementation of the public Element transform(ElementGroup arg0,
List<Element> arg1).
In particular, if I start with (1) I obtain some results, if I start with
(2) I obtain something different (you can see below the details).
I have also used ElementTransformCleanGroupsOfOne when ElementGroup is
empty
ElementTransform transform = new
ElementTransformCleanGroupsOfOne();
Element el2 = ElementTransformer.transform(eg, transform);
return el2;
but no difference in results. I am sure I am doing something wrong.
Moreover, my questions are: what is the main difference between the two
approaches? and when I should use ElementGroup arg0 and when List<Element>
arg1?
(1) public Element transform(ElementGroup arg0, List<Element> arg1) {
List<Element> elemList = arg0.getElements();
Iterator<Element> itr = elemList.iterator();
while (itr.hasNext()) {
}
…
…
}
(2) public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
}
…
…
}
I know that it may be related to the little knowledge about Jena.
Many Thanks in advice for your clarification on the above.
Best Regards,
Carlo
=======
Below, I reported the used code (at very bottom), the two used scenario
with test-cases and results. In practice, you can notice that:
==== TESTING:
Scenario A:
public Element transform(ElementGroup arg0, List<Element> arg1) {
List<Element> elemList = arg0.getElements();
Iterator<Element> itr = elemList.iterator();
while (itr.hasNext()) {
}
…
…
}
Test 1:
The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
=========== BEFORE Q1
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name
OPTIONAL
{ ?x foaf:mbox ?mbox }
}
============= AFTER Q1
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name }
Test2:
The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
query Q2:
=========== BEFORE Q2
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z
OPTIONAL
{ ?boss1 ex:isBossOf1 ?ind }
}
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
============= AFTER Q2: it does not remove the triple.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
Q3:
=========== BEFORE Q3:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ ?ind rdf:type ?z
FILTER ( ?ind = "mathieu" )
}
============= AFTER Q3: There is still an empty BGP present.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ # Empty BGP
}
Scenario B:
public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
}
…
…
}
Test 1:
The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
=========== BEFORE Q1
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name
OPTIONAL
{ ?x foaf:mbox ?mbox }
}
============= AFTER Q1: there is still the OPTION (with a ElementGroup
empty) clause.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name
OPTIONAL
{ # Empty BGP
}
}
Test 2:
The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
query Q2:
=========== BEFORE Q2
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z
OPTIONAL
{ ?boss1 ex:isBossOf1 ?ind }
}
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
============= AFTER Q2: it does not remove the OPTION and it leaves an
empty BGP.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z
OPTIONAL
{ # Empty BGP
}
}
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
Q3:
=========== BEFORE Q3
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ ?ind rdf:type ?z
FILTER ( ?ind = "mathieu" )
}
============= AFTER Q3: It does not remove the FILTER, but just the triple.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ # Empty BGP
FILTER ( ?boss = "mathieu" )
}
}
=== FULL CODE used with public Element transform(ElementPathBlock
eltPB)
@Override
public Element transform(ElementPathBlock eltPB) {
if (eltPB.isEmpty()) {
//System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
ElementPathBlock IS EMPTY:: " + eltPB.toString());
return eltPB;
}
System.out.println("[RemoveOpTransform::transform(ElementPathBlock
arg0)] ElementPathBlock:: " + eltPB.toString());
Iterator<TriplePath> l = eltPB.patternElts();
while (l.hasNext()) {
TriplePath tp = l.next();
if (tp.asTriple().matches(this.triple)) {
l.remove();
System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
ElementPathBlock:: " + tp.toString() + " TRIPLE JUST REMOVED!!!");
//System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
TRIPLE JUST REMOVED!!! ");
System.out.println("");
return this.transform(eltPB);//eltPB;
}
}
return eltPB;
}
=== FULL CODE used with public Element transform(ElementGroup arg0,
List<Element> arg1)
@Override
public Element transform(ElementGroup arg0, List<Element> arg1) {
List<Element> elemList = arg0.getElements();
Iterator<Element> itr = elemList.iterator();
//Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
Element elem = itr.next();
if (elem instanceof ElementOptional) {
boolean isElementOptionalEmpty =
isElementOptionalEmpty((ElementOptional) elem);
if (isElementOptionalEmpty) {
itr.remove();
}
}
else if (elem instanceof ElementGroup) {
boolean isElementGroupEmpty =
isElementGroupEmpty((ElementGroup) elem);
if (isElementGroupEmpty) {
itr.remove();
}
}
else if (elem instanceof ElementFilter) {
//... check if this filter is the one that we should remove
//...get the variables of the triple pattern that we want
to delete
Set<Var> tpVars = new HashSet();
Node subj = this.triple.getSubject();
if (subj.isVariable()) {
tpVars.add((Var) subj);
}
Node pred = this.triple.getPredicate();
if (pred.isVariable()) {
tpVars.add((Var) pred);
}
Node obj = this.triple.getObject();
if (obj.isVariable()) {
tpVars.add((Var) obj);
}
//...get the variables of the FILTER expression
Set<Var> expVars = ((ElementFilter)
elem).getExpr().getVarsMentioned();
//...check whether the FILTER expression contains any of
the triple pattern variable
for (Var var : expVars) {
//..if it does then we have to delete the entire
FILTER expression
if (tpVars.contains(var)) {
itr.remove();
}
}
}
else if (elem instanceof ElementUnion) {
boolean isUnionBothSidesEmpty =
isUnionBothSidesEmpty1((ElementUnion) elem);
if (isUnionBothSidesEmpty) {
itr.remove();
}
}
}
return arg0;
}
On 2 Feb 2016, at 10:54, Carlo.Allocca <ca...@open.ac.uk><mailto:
carlo.allocca@open.ac.uk<ma...@open.ac.uk>>> wrote:
Dear Andy,
Thank you for your time. Very appreciated.
Some comments follow in lines.
On 2 Feb 2016, at 09:36, Andy Seaborne <an...@apache.org><mailto:
andy@apache.org<ma...@apache.org>>> wrote:
when removing the triple (?boss ex:isBossOf ?ind .”), I get
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ # Empty BGP
}
}
}
which is OK.
I just need to find out how to remove an ElementGroup which contains only
one element which is the EMPTY one.
Of course, I need to do the same for the other case, e.g. OPTION,
SUBquery, etc.
Do note that evaluating {} (empty syntax group) yields one row of zero
columns - it contributes to the overall results (it's the join identity).
I see. To avoid this I am going to apply a
ElementTransformCleanGroupsOfOne as you suggested.
Now you have to look at all the elements that have a group in
ElementUnion, ElementOptional, ElementMinus, …
Yes, I need to cover all the SPARQL language from the “public Element
transform(ElementGroup arg0, List<Element> arg1)” call.
At least this is my understanding so far.
That is what ElementTransformCleanGroupsOfOne does, except it looks for
"groups of one"
.. UNION { { stuff } }
and isn't to fussy about finding them all (it's an optimization, more a
tidying of the tree, not a change in the effect of a query which is what
removing triple patterns is).
And of course changes from the bottom could potentially cause change all
the way up to the top of the syntax tree.
also: they maybe be original, legal empty groups in the tree.
Thanks for the detailed clarifications. Indeed, I will consider them.
Many Thanks,
Best Regards,
Carlo
Andy
-- The Open University is incorporated by Royal Charter (RC 000391), an
exempt charity in England & Wales and a charity registered in Scotland (SC
038302). The Open University is authorised and regulated by the Financial
Conduct Authority.
-- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Dear Andy and All,
sorry for this long thread.
I am sure I was not able to put in practice some of your suggestions.
I put the full code here http://collabedit.com/wfhtq and reported below.
I tested it over the Q1 with the triple (?boss ex:isBossOf ?ind).
=========== BEFORE Q1:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
============= AFTER Q1:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ # Empty BGP
FILTER ( ?boss = "mathieu" )
}
}
But the filter is still there even if when I trace the execution it removes it.
I am doing the update between the AST and remove of the filter in
@Override
public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
Element elem = itr.next();
…
...
}
//With this code I am saying the following: make effective all the modifications that //have been made so far, if any.
if (arg0.getElements() == arg1)
{ return arg0; }
else {
ElementGroup el2 = new ElementGroup();
el2.getElements().addAll(arg1);
return el2;
}
}
What am I doing wrong?
Many Thanks for your help.
Best Regards,
Carlo
=== Code
//The main Class
public class RemoveTriple {
public RemoveTriple(){
super();
}
public Query removeTP(Query q, Triple tp) {
RemoveOpTransform rOpTransform = new RemoveOpTransform(q,tp);
Query queryWithoutTriplePattern = QueryTransformOps.transform(q, rOpTransform) ;
return queryWithoutTriplePattern;
}
}
// The current implementation of the RemoveOpTransform class. The class that implements the removal of the triple
public class RemoveOpTransform implements ElementTransform {
private Query query;
private Triple triple;
public RemoveOpTransform(Query q, Triple tp) {
this.query = q;
this.triple = tp;
}
@Override
public Element transform(ElementTriplesBlock arg0) {
System.out.println("[RemoveOpTransform::transform(ElementTriplesBlock arg0)] " + arg0.toString());
System.out.println("");
return arg0;
}
// This is the code related to the
@Override
public Element transform(ElementPathBlock eltPB) {
if (eltPB.isEmpty()) {
return eltPB;
}
Iterator<TriplePath> l = eltPB.patternElts();
while (l.hasNext()) {
TriplePath tp = l.next();
if (tp.asTriple().matches(this.triple)) {
l.remove();
return this.transform(eltPB);//eltPB;
}
}
return eltPB;
}
@Override
public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
Element elem = itr.next();
// I should go one by one the and examinate all the possible cases. For example:
//UNNION
if (elem instanceof ElementUnion) {
if (isUnionBothSidesEmpty) {
itr.remove();
}
}
//OPTION
if (elem instanceof ElementOptional) {
boolean isElementOptionalEmpty = isElementOptionalEmpty((ElementOptional) elem);
if (isElementOptionalEmpty) {
itr.remove();
// ElementGroup el2 = new ElementGroup();
// el2.getElements().addAll(arg1);
// return el2;
}
}
//ELEMENTGROUP
if (elem instanceof ElementGroup) {
boolean isElementGroupEmpty = isElementGroupEmpty((ElementGroup) elem);
if (isElementGroupEmpty) {
itr.remove();
// ElementGroup el2 = new ElementGroup();
// el2.getElements().addAll(arg1);
// return el2;
}
}
//FILTER
if (elem instanceof ElementFilter) {
//... check if this filter is the one that we should remove
//...get the variables of the triple pattern that we want to delete
Set<Var> tpVars = new HashSet();
Node subj = this.triple.getSubject();
if (subj.isVariable()) {
tpVars.add((Var) subj);
}
Node pred = this.triple.getPredicate();
if (pred.isVariable()) {
tpVars.add((Var) pred);
}
Node obj = this.triple.getObject();
if (obj.isVariable()) {
tpVars.add((Var) obj);
}
//...get the variables of the FILTER expression
Set<Var> expVars = ((ElementFilter) elem).getExpr().getVarsMentioned();
//...check whether the FILTER expression contains any of the triple pattern variable
for (Var var : expVars) {
//...if it does then we can delete the entire FILTER expression
if (tpVars.contains(var)) {
itr.remove();
break;
}
}
}
}// End of While
//With this code I am saying the following: make effective all the modifications that
//have been made so far, if any.
if (arg0.getElements() == arg1) {
return arg0;
} else {
ElementGroup el2 = new ElementGroup();
el2.getElements().addAll(arg1);
return el2;
}
}
@Override
public Element transform(ElementFilter arg0, Expr arg1) {
return arg0;
}
@Override
public Element transform(ElementAssign arg0, Var arg1, Expr arg2) {
return arg0;
}
@Override
public Element transform(ElementBind arg0, Var arg1, Expr arg2) {
System.out.println("[RemoveOpTransform::transform(ElementBind arg0)] " + arg0.toString());
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementData arg0) {
System.out.println("[RemoveOpTransform::transform(ElementData arg0)] " + arg0.toString());
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementDataset arg0, Element arg1) {
System.out.println("[RemoveOpTransform::transform(ElementDataset arg0)] " + arg0.toString());
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementUnion arg0, List<Element> arg1) {
System.out.println("[RemoveOpTransform::transform(ElementUnion arg0)] arg0 " + arg0.toString());
System.out.println("[RemoveOpTransform::transform(ElementUnion arg0)] arg1 " + arg1.toString());
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementOptional arg0, Element arg1) {
return arg0;
}
@Override
public Element transform(ElementNamedGraph arg0, Node arg1, Element arg2) {
System.out.println("[RemoveOpTransform::transform(ElementNamedGraph arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementExists arg0, Element arg1) {
System.out.println("[RemoveOpTransform::transform(ElementExists arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementNotExists arg0, Element arg1) {
System.out.println("[RemoveOpTransform::transform(ElementNotExists arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementMinus arg0, Element arg1) {
System.out.println("[RemoveOpTransform::transform(ElementMinus arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementService arg0, Node arg1, Element arg2) {
System.out.println("[RemoveOpTransform::transform(ElementService arg0)] ");
System.out.println("");
return arg0;
}
@Override
public Element transform(ElementSubQuery arg0, Query arg1) {
System.out.println("[RemoveOpTransform::transform(ElementSubQuery arg0)] ");
System.out.println("");
return arg0;
}
private boolean isUnionBothSidesEmpty1(ElementUnion elementUnion) {
List<Element> elemListUnion = elementUnion.getElements();//.getElements();
if (elemListUnion.size() == 2) {
Element left = elemListUnion.get(0);
Element right = elemListUnion.get(1);
if (left instanceof ElementGroup && right instanceof ElementGroup) {
if ((((ElementGroup) left).getElements().size() == 1) && (((ElementGroup) right).getElements().size() == 1)) {
Element elLeft = ((ElementGroup) left).getElements().get(0);
Element elRight = ((ElementGroup) right).getElements().get(0);
if ((elLeft instanceof ElementPathBlock) && (elRight instanceof ElementPathBlock)) {
ElementPathBlock epbLeft = (ElementPathBlock) elLeft;
ElementPathBlock epbRight = (ElementPathBlock) elRight;
if (epbLeft.isEmpty() && epbRight.isEmpty()) {
return true;
}
}
}
}
}
return false;
}
private boolean isElementGroupEmpty(ElementGroup elementGroup) {
List<Element> elList = ((ElementGroup) elementGroup).getElements();
if (elList.size() == 1) {
Element el = (Element) elList.get(0);
if (el instanceof ElementPathBlock) {
ElementPathBlock tmp = (ElementPathBlock) el;
if (tmp.isEmpty()) {
return true;
}
}
}
return false;
}
private boolean isElementOptionalEmpty(ElementOptional elementOptional) {
Element elm = ((ElementOptional) elementOptional).getOptionalElement();//.getElements();
if (elm instanceof ElementGroup) {
List<Element> elList = ((ElementGroup) elm).getElements();
if (elList.size() == 1) {
Element el = (Element) elList.get(0);
if (el instanceof ElementPathBlock) {
ElementPathBlock tmp = (ElementPathBlock) el;
if (tmp.isEmpty()) {
return true;
}
}
}
}
return false;
}
}
On 3 Feb 2016, at 00:00, Carlo.Allocca <ca...@open.ac.uk>> wrote:
Dear Andy and Paul,
some comments follow in lines.
On 2 Feb 2016, at 22:33, Andy Seaborne <an...@apache.org>> wrote:
On 02/02/16 19:29, Paul Houle wrote:
Carlo, Andy,
I like the Iterator<> interfaces in the Jena framework for getting data
out, but I make a habit of always putting results in a List or Queue or
something before putting them back into the same Jena model because i get
less BS per mile that way in terms of Exceptions and other exceptional
events.
Does Jena have an official policy on being reenterable in that way?
Carlo's issues are nothing to do with iterator policy.
Carlo - Use arg1 else you will not see your changes so far.
In
public Element transform(ElementGroup arg0, List<Element> arg1)
arg0 is the element from the AST before modification and
arg1 is the new elements to go in after modification by lower levels of the bottom-up rewrite.
So if you rewrite a ElementFilter by making a new one, it will appear in arg1 not in arg0.
I see. Thank you. Based on this, I am going to use "Iterator<Element> itr = arg1.iterator(); when implementing
public Element transform(ElementGroup arg0, List<Element> arg1).
Do not modify the Element* arguments in place.
See ElementTransformCopyBase
The default implementation is:
@Override
public Element transform(ElementGroup el, List<Element> elts) {
if ( el.getElements() == elts )
return el ;
ElementGroup el2 = new ElementGroup() ;
el2.getElements().addAll(elts) ;
return el2 ;
}
i.e if any change, detected by being not the exact identical list, then do a copy of the structure. This saves object churn.
I am going to change my implementation in such a way include all the above suggestions and clarifications.
Many Thanks for your willingness.
Best Regards,
Carlo.
Andy
On Tue, Feb 2, 2016 at 2:13 PM, Carlo.Allocca <ca...@open.ac.uk>>
wrote:
Dear Andy and All,
while I was extending and testing the code that I wrote so far concerning
the removing a triple from a given SPARQL query,
I realised that I get different outputs depending on how I start the
implementation of the public Element transform(ElementGroup arg0,
List<Element> arg1).
In particular, if I start with (1) I obtain some results, if I start with
(2) I obtain something different (you can see below the details).
I have also used ElementTransformCleanGroupsOfOne when ElementGroup is
empty
ElementTransform transform = new
ElementTransformCleanGroupsOfOne();
Element el2 = ElementTransformer.transform(eg, transform);
return el2;
but no difference in results. I am sure I am doing something wrong.
Moreover, my questions are: what is the main difference between the two
approaches? and when I should use ElementGroup arg0 and when List<Element>
arg1?
(1) public Element transform(ElementGroup arg0, List<Element> arg1) {
List<Element> elemList = arg0.getElements();
Iterator<Element> itr = elemList.iterator();
while (itr.hasNext()) {
}
…
…
}
(2) public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
}
…
…
}
I know that it may be related to the little knowledge about Jena.
Many Thanks in advice for your clarification on the above.
Best Regards,
Carlo
=======
Below, I reported the used code (at very bottom), the two used scenario
with test-cases and results. In practice, you can notice that:
==== TESTING:
Scenario A:
public Element transform(ElementGroup arg0, List<Element> arg1) {
List<Element> elemList = arg0.getElements();
Iterator<Element> itr = elemList.iterator();
while (itr.hasNext()) {
}
…
…
}
Test 1:
The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
=========== BEFORE Q1
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name
OPTIONAL
{ ?x foaf:mbox ?mbox }
}
============= AFTER Q1
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name }
Test2:
The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
query Q2:
=========== BEFORE Q2
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z
OPTIONAL
{ ?boss1 ex:isBossOf1 ?ind }
}
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
============= AFTER Q2: it does not remove the triple.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
Q3:
=========== BEFORE Q3:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ ?ind rdf:type ?z
FILTER ( ?ind = "mathieu" )
}
============= AFTER Q3: There is still an empty BGP present.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ # Empty BGP
}
Scenario B:
public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
}
…
…
}
Test 1:
The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
=========== BEFORE Q1
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name
OPTIONAL
{ ?x foaf:mbox ?mbox }
}
============= AFTER Q1: there is still the OPTION (with a ElementGroup
empty) clause.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name
OPTIONAL
{ # Empty BGP
}
}
Test 2:
The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
query Q2:
=========== BEFORE Q2
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z
OPTIONAL
{ ?boss1 ex:isBossOf1 ?ind }
}
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
============= AFTER Q2: it does not remove the OPTION and it leaves an
empty BGP.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z
OPTIONAL
{ # Empty BGP
}
}
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
Q3:
=========== BEFORE Q3
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ ?ind rdf:type ?z
FILTER ( ?ind = "mathieu" )
}
============= AFTER Q3: It does not remove the FILTER, but just the triple.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ # Empty BGP
FILTER ( ?boss = "mathieu" )
}
}
=== FULL CODE used with public Element transform(ElementPathBlock
eltPB)
@Override
public Element transform(ElementPathBlock eltPB) {
if (eltPB.isEmpty()) {
//System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
ElementPathBlock IS EMPTY:: " + eltPB.toString());
return eltPB;
}
System.out.println("[RemoveOpTransform::transform(ElementPathBlock
arg0)] ElementPathBlock:: " + eltPB.toString());
Iterator<TriplePath> l = eltPB.patternElts();
while (l.hasNext()) {
TriplePath tp = l.next();
if (tp.asTriple().matches(this.triple)) {
l.remove();
System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
ElementPathBlock:: " + tp.toString() + " TRIPLE JUST REMOVED!!!");
//System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
TRIPLE JUST REMOVED!!! ");
System.out.println("");
return this.transform(eltPB);//eltPB;
}
}
return eltPB;
}
=== FULL CODE used with public Element transform(ElementGroup arg0,
List<Element> arg1)
@Override
public Element transform(ElementGroup arg0, List<Element> arg1) {
List<Element> elemList = arg0.getElements();
Iterator<Element> itr = elemList.iterator();
//Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
Element elem = itr.next();
if (elem instanceof ElementOptional) {
boolean isElementOptionalEmpty =
isElementOptionalEmpty((ElementOptional) elem);
if (isElementOptionalEmpty) {
itr.remove();
}
}
else if (elem instanceof ElementGroup) {
boolean isElementGroupEmpty =
isElementGroupEmpty((ElementGroup) elem);
if (isElementGroupEmpty) {
itr.remove();
}
}
else if (elem instanceof ElementFilter) {
//... check if this filter is the one that we should remove
//...get the variables of the triple pattern that we want
to delete
Set<Var> tpVars = new HashSet();
Node subj = this.triple.getSubject();
if (subj.isVariable()) {
tpVars.add((Var) subj);
}
Node pred = this.triple.getPredicate();
if (pred.isVariable()) {
tpVars.add((Var) pred);
}
Node obj = this.triple.getObject();
if (obj.isVariable()) {
tpVars.add((Var) obj);
}
//...get the variables of the FILTER expression
Set<Var> expVars = ((ElementFilter)
elem).getExpr().getVarsMentioned();
//...check whether the FILTER expression contains any of
the triple pattern variable
for (Var var : expVars) {
//..if it does then we have to delete the entire
FILTER expression
if (tpVars.contains(var)) {
itr.remove();
}
}
}
else if (elem instanceof ElementUnion) {
boolean isUnionBothSidesEmpty =
isUnionBothSidesEmpty1((ElementUnion) elem);
if (isUnionBothSidesEmpty) {
itr.remove();
}
}
}
return arg0;
}
On 2 Feb 2016, at 10:54, Carlo.Allocca <ca...@open.ac.uk><mailto:
carlo.allocca@open.ac.uk<ma...@open.ac.uk>>> wrote:
Dear Andy,
Thank you for your time. Very appreciated.
Some comments follow in lines.
On 2 Feb 2016, at 09:36, Andy Seaborne <an...@apache.org><mailto:
andy@apache.org<ma...@apache.org>>> wrote:
when removing the triple (?boss ex:isBossOf ?ind .”), I get
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ # Empty BGP
}
}
}
which is OK.
I just need to find out how to remove an ElementGroup which contains only
one element which is the EMPTY one.
Of course, I need to do the same for the other case, e.g. OPTION,
SUBquery, etc.
Do note that evaluating {} (empty syntax group) yields one row of zero
columns - it contributes to the overall results (it's the join identity).
I see. To avoid this I am going to apply a
ElementTransformCleanGroupsOfOne as you suggested.
Now you have to look at all the elements that have a group in
ElementUnion, ElementOptional, ElementMinus, …
Yes, I need to cover all the SPARQL language from the “public Element
transform(ElementGroup arg0, List<Element> arg1)” call.
At least this is my understanding so far.
That is what ElementTransformCleanGroupsOfOne does, except it looks for
"groups of one"
.. UNION { { stuff } }
and isn't to fussy about finding them all (it's an optimization, more a
tidying of the tree, not a change in the effect of a query which is what
removing triple patterns is).
And of course changes from the bottom could potentially cause change all
the way up to the top of the syntax tree.
also: they maybe be original, legal empty groups in the tree.
Thanks for the detailed clarifications. Indeed, I will consider them.
Many Thanks,
Best Regards,
Carlo
Andy
-- The Open University is incorporated by Royal Charter (RC 000391), an
exempt charity in England & Wales and a charity registered in Scotland (SC
038302). The Open University is authorised and regulated by the Financial
Conduct Authority.
-- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Dear Andy and Paul,
some comments follow in lines.
> On 2 Feb 2016, at 22:33, Andy Seaborne <an...@apache.org> wrote:
>
> On 02/02/16 19:29, Paul Houle wrote:
>> Carlo, Andy,
>>
>> I like the Iterator<> interfaces in the Jena framework for getting data
>> out, but I make a habit of always putting results in a List or Queue or
>> something before putting them back into the same Jena model because i get
>> less BS per mile that way in terms of Exceptions and other exceptional
>> events.
>>
>> Does Jena have an official policy on being reenterable in that way?
>
> Carlo's issues are nothing to do with iterator policy.
>
> Carlo - Use arg1 else you will not see your changes so far.
>
> In
>
> public Element transform(ElementGroup arg0, List<Element> arg1)
>
> arg0 is the element from the AST before modification and
> arg1 is the new elements to go in after modification by lower levels of the bottom-up rewrite.
>
>
> So if you rewrite a ElementFilter by making a new one, it will appear in arg1 not in arg0.
I see. Thank you. Based on this, I am going to use "Iterator<Element> itr = arg1.iterator(); when implementing
public Element transform(ElementGroup arg0, List<Element> arg1).
> Do not modify the Element* arguments in place.
>
>
> See ElementTransformCopyBase
>
> The default implementation is:
>
> @Override
> public Element transform(ElementGroup el, List<Element> elts) {
> if ( el.getElements() == elts )
> return el ;
> ElementGroup el2 = new ElementGroup() ;
> el2.getElements().addAll(elts) ;
> return el2 ;
> }
>
>
> i.e if any change, detected by being not the exact identical list, then do a copy of the structure. This saves object churn.
>
I am going to change my implementation in such a way include all the above suggestions and clarifications.
Many Thanks for your willingness.
Best Regards,
Carlo.
> Andy
>
>>
>> On Tue, Feb 2, 2016 at 2:13 PM, Carlo.Allocca <ca...@open.ac.uk>
>> wrote:
>>
>>>
>>> Dear Andy and All,
>>>
>>> while I was extending and testing the code that I wrote so far concerning
>>> the removing a triple from a given SPARQL query,
>>> I realised that I get different outputs depending on how I start the
>>> implementation of the public Element transform(ElementGroup arg0,
>>> List<Element> arg1).
>>> In particular, if I start with (1) I obtain some results, if I start with
>>> (2) I obtain something different (you can see below the details).
>>>
>>> I have also used ElementTransformCleanGroupsOfOne when ElementGroup is
>>> empty
>>> ElementTransform transform = new
>>> ElementTransformCleanGroupsOfOne();
>>> Element el2 = ElementTransformer.transform(eg, transform);
>>> return el2;
>>>
>>> but no difference in results. I am sure I am doing something wrong.
>>> Moreover, my questions are: what is the main difference between the two
>>> approaches? and when I should use ElementGroup arg0 and when List<Element>
>>> arg1?
>>>
>>>
>>> (1) public Element transform(ElementGroup arg0, List<Element> arg1) {
>>> List<Element> elemList = arg0.getElements();
>>> Iterator<Element> itr = elemList.iterator();
>>> while (itr.hasNext()) {
>>>
>>>
>>> }
>>> …
>>> …
>>> }
>>>
>>>
>>> (2) public Element transform(ElementGroup arg0, List<Element> arg1) {
>>>
>>>
>>>
>>> Iterator<Element> itr = arg1.iterator();
>>> while (itr.hasNext()) {
>>>
>>>
>>> }
>>> …
>>> …
>>> }
>>>
>>> I know that it may be related to the little knowledge about Jena.
>>> Many Thanks in advice for your clarification on the above.
>>>
>>> Best Regards,
>>> Carlo
>>>
>>>
>>> =======
>>>
>>> Below, I reported the used code (at very bottom), the two used scenario
>>> with test-cases and results. In practice, you can notice that:
>>>
>>>
>>>
>>> ==== TESTING:
>>>
>>> Scenario A:
>>>
>>> public Element transform(ElementGroup arg0, List<Element> arg1) {
>>>
>>>
>>>
>>> List<Element> elemList = arg0.getElements();
>>> Iterator<Element> itr = elemList.iterator();
>>> while (itr.hasNext()) {
>>>
>>>
>>> }
>>> …
>>> …
>>> }
>>>
>>>
>>> Test 1:
>>>
>>> The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
>>>
>>> =========== BEFORE Q1
>>>
>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>>>
>>> SELECT DISTINCT ?name ?mbox
>>> WHERE
>>> { ?x foaf:name ?name
>>> OPTIONAL
>>> { ?x foaf:mbox ?mbox }
>>> }
>>>
>>>
>>> ============= AFTER Q1
>>>
>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>>>
>>> SELECT DISTINCT ?name ?mbox
>>> WHERE
>>> { ?x foaf:name ?name }
>>>
>>>
>>> Test2:
>>>
>>> The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
>>> query Q2:
>>>
>>>
>>>
>>> =========== BEFORE Q2
>>>
>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>>
>>> SELECT DISTINCT ?ind ?boss ?g
>>> WHERE
>>> { { ?ind rdf:type ?z
>>> OPTIONAL
>>> { ?boss1 ex:isBossOf1 ?ind }
>>> }
>>> UNION
>>> { { ?boss ex:isBossOf1 ?ind }
>>> UNION
>>> { ?boss ex:isBossOf ?ind
>>> FILTER ( ?boss = "mathieu" )
>>> }
>>> }
>>> }
>>>
>>> ============= AFTER Q2: it does not remove the triple.
>>>
>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>>
>>> SELECT DISTINCT ?ind ?boss ?g
>>> WHERE
>>> { { ?ind rdf:type ?z }
>>> UNION
>>> { { ?boss ex:isBossOf1 ?ind }
>>> UNION
>>> { ?boss ex:isBossOf ?ind
>>> FILTER ( ?boss = "mathieu" )
>>> }
>>> }
>>> }
>>>
>>>
>>> Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
>>> Q3:
>>>
>>> =========== BEFORE Q3:
>>>
>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>>
>>> SELECT DISTINCT ?ind ?boss ?g
>>> WHERE
>>> { ?ind rdf:type ?z
>>> FILTER ( ?ind = "mathieu" )
>>> }
>>>
>>> ============= AFTER Q3: There is still an empty BGP present.
>>>
>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>>
>>> SELECT DISTINCT ?ind ?boss ?g
>>> WHERE
>>> { # Empty BGP
>>>
>>>
>>>
>>> }
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> Scenario B:
>>>
>>> public Element transform(ElementGroup arg0, List<Element> arg1) {
>>>
>>>
>>>
>>> Iterator<Element> itr = arg1.iterator();
>>> while (itr.hasNext()) {
>>>
>>>
>>> }
>>> …
>>> …
>>> }
>>>
>>>
>>> Test 1:
>>>
>>> The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
>>>
>>> =========== BEFORE Q1
>>>
>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>>>
>>> SELECT DISTINCT ?name ?mbox
>>> WHERE
>>> { ?x foaf:name ?name
>>> OPTIONAL
>>> { ?x foaf:mbox ?mbox }
>>> }
>>>
>>>
>>> ============= AFTER Q1: there is still the OPTION (with a ElementGroup
>>> empty) clause.
>>>
>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>>>
>>> SELECT DISTINCT ?name ?mbox
>>> WHERE
>>> { ?x foaf:name ?name
>>> OPTIONAL
>>> { # Empty BGP
>>>
>>>
>>>
>>> }
>>> }
>>>
>>>
>>>
>>>
>>> Test 2:
>>>
>>> The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
>>> query Q2:
>>>
>>>
>>>
>>> =========== BEFORE Q2
>>>
>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>>
>>> SELECT DISTINCT ?ind ?boss ?g
>>> WHERE
>>> { { ?ind rdf:type ?z
>>> OPTIONAL
>>> { ?boss1 ex:isBossOf1 ?ind }
>>> }
>>> UNION
>>> { { ?boss ex:isBossOf1 ?ind }
>>> UNION
>>> { ?boss ex:isBossOf ?ind
>>> FILTER ( ?boss = "mathieu" )
>>> }
>>> }
>>> }
>>>
>>> ============= AFTER Q2: it does not remove the OPTION and it leaves an
>>> empty BGP.
>>>
>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>>
>>> SELECT DISTINCT ?ind ?boss ?g
>>> WHERE
>>> { { ?ind rdf:type ?z
>>> OPTIONAL
>>> { # Empty BGP
>>>
>>>
>>>
>>> }
>>> }
>>> UNION
>>> { { ?boss ex:isBossOf1 ?ind }
>>> UNION
>>> { ?boss ex:isBossOf ?ind
>>> FILTER ( ?boss = "mathieu" )
>>> }
>>> }
>>> }
>>>
>>> Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
>>> Q3:
>>>
>>> =========== BEFORE Q3
>>>
>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>>
>>> SELECT DISTINCT ?ind ?boss ?g
>>> WHERE
>>> { ?ind rdf:type ?z
>>> FILTER ( ?ind = "mathieu" )
>>> }
>>>
>>> ============= AFTER Q3: It does not remove the FILTER, but just the triple.
>>>
>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>>
>>> SELECT DISTINCT ?ind ?boss ?g
>>> WHERE
>>> { { ?ind rdf:type ?z }
>>> UNION
>>> { # Empty BGP
>>>
>>>
>>>
>>> FILTER ( ?boss = "mathieu" )
>>> }
>>> }
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> === FULL CODE used with public Element transform(ElementPathBlock
>>> eltPB)
>>>
>>> @Override
>>> public Element transform(ElementPathBlock eltPB) {
>>> if (eltPB.isEmpty()) {
>>>
>>> //System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
>>> ElementPathBlock IS EMPTY:: " + eltPB.toString());
>>> return eltPB;
>>> }
>>> System.out.println("[RemoveOpTransform::transform(ElementPathBlock
>>> arg0)] ElementPathBlock:: " + eltPB.toString());
>>> Iterator<TriplePath> l = eltPB.patternElts();
>>> while (l.hasNext()) {
>>> TriplePath tp = l.next();
>>> if (tp.asTriple().matches(this.triple)) {
>>> l.remove();
>>>
>>> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
>>> ElementPathBlock:: " + tp.toString() + " TRIPLE JUST REMOVED!!!");
>>>
>>> //System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
>>> TRIPLE JUST REMOVED!!! ");
>>> System.out.println("");
>>> return this.transform(eltPB);//eltPB;
>>> }
>>> }
>>> return eltPB;
>>> }
>>>
>>>
>>> === FULL CODE used with public Element transform(ElementGroup arg0,
>>> List<Element> arg1)
>>>
>>> @Override
>>> public Element transform(ElementGroup arg0, List<Element> arg1) {
>>>
>>>
>>>
>>> List<Element> elemList = arg0.getElements();
>>> Iterator<Element> itr = elemList.iterator();
>>> //Iterator<Element> itr = arg1.iterator();
>>> while (itr.hasNext()) {
>>> Element elem = itr.next();
>>> if (elem instanceof ElementOptional) {
>>> boolean isElementOptionalEmpty =
>>> isElementOptionalEmpty((ElementOptional) elem);
>>> if (isElementOptionalEmpty) {
>>> itr.remove();
>>> }
>>> }
>>>
>>> else if (elem instanceof ElementGroup) {
>>> boolean isElementGroupEmpty =
>>> isElementGroupEmpty((ElementGroup) elem);
>>> if (isElementGroupEmpty) {
>>> itr.remove();
>>> }
>>> }
>>> else if (elem instanceof ElementFilter) {
>>> //... check if this filter is the one that we should remove
>>> //...get the variables of the triple pattern that we want
>>> to delete
>>> Set<Var> tpVars = new HashSet();
>>> Node subj = this.triple.getSubject();
>>> if (subj.isVariable()) {
>>> tpVars.add((Var) subj);
>>> }
>>> Node pred = this.triple.getPredicate();
>>> if (pred.isVariable()) {
>>> tpVars.add((Var) pred);
>>> }
>>> Node obj = this.triple.getObject();
>>> if (obj.isVariable()) {
>>> tpVars.add((Var) obj);
>>> }
>>> //...get the variables of the FILTER expression
>>> Set<Var> expVars = ((ElementFilter)
>>> elem).getExpr().getVarsMentioned();
>>> //...check whether the FILTER expression contains any of
>>> the triple pattern variable
>>> for (Var var : expVars) {
>>> //..if it does then we have to delete the entire
>>> FILTER expression
>>> if (tpVars.contains(var)) {
>>> itr.remove();
>>> }
>>> }
>>> }
>>> else if (elem instanceof ElementUnion) {
>>> boolean isUnionBothSidesEmpty =
>>> isUnionBothSidesEmpty1((ElementUnion) elem);
>>> if (isUnionBothSidesEmpty) {
>>> itr.remove();
>>> }
>>> }
>>>
>>> }
>>> return arg0;
>>> }
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> On 2 Feb 2016, at 10:54, Carlo.Allocca <carlo.allocca@open.ac.uk<mailto:
>>> carlo.allocca@open.ac.uk>> wrote:
>>>
>>> Dear Andy,
>>>
>>> Thank you for your time. Very appreciated.
>>> Some comments follow in lines.
>>>
>>> On 2 Feb 2016, at 09:36, Andy Seaborne <andy@apache.org<mailto:
>>> andy@apache.org>> wrote:
>>>
>>>
>>> when removing the triple (?boss ex:isBossOf ?ind .”), I get
>>>
>>> SELECT DISTINCT ?ind ?boss ?g
>>> WHERE
>>> { { ?ind rdf:type ?z }
>>> UNION
>>> { { ?boss ex:isBossOf1 ?ind }
>>> UNION
>>> { # Empty BGP
>>>
>>> }
>>> }
>>> }
>>>
>>> which is OK.
>>> I just need to find out how to remove an ElementGroup which contains only
>>> one element which is the EMPTY one.
>>> Of course, I need to do the same for the other case, e.g. OPTION,
>>> SUBquery, etc.
>>>
>>> Do note that evaluating {} (empty syntax group) yields one row of zero
>>> columns - it contributes to the overall results (it's the join identity).
>>>
>>> I see. To avoid this I am going to apply a
>>> ElementTransformCleanGroupsOfOne as you suggested.
>>>
>>>
>>> Now you have to look at all the elements that have a group in
>>> ElementUnion, ElementOptional, ElementMinus, …
>>> Yes, I need to cover all the SPARQL language from the “public Element
>>> transform(ElementGroup arg0, List<Element> arg1)” call.
>>> At least this is my understanding so far.
>>>
>>>
>>>
>>> That is what ElementTransformCleanGroupsOfOne does, except it looks for
>>> "groups of one"
>>>
>>> .. UNION { { stuff } }
>>>
>>> and isn't to fussy about finding them all (it's an optimization, more a
>>> tidying of the tree, not a change in the effect of a query which is what
>>> removing triple patterns is).
>>>
>>> And of course changes from the bottom could potentially cause change all
>>> the way up to the top of the syntax tree.
>>>
>>> also: they maybe be original, legal empty groups in the tree.
>>>
>>> Thanks for the detailed clarifications. Indeed, I will consider them.
>>>
>>> Many Thanks,
>>> Best Regards,
>>> Carlo
>>>
>>>
>>>
>>> Andy
>>>
>>>
>>>
>>>
>>>
>>>
>>> -- The Open University is incorporated by Royal Charter (RC 000391), an
>>> exempt charity in England & Wales and a charity registered in Scotland (SC
>>> 038302). The Open University is authorised and regulated by the Financial
>>> Conduct Authority.
>>>
>>>
>>
>>
>
-- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
Re: How to remove consistently a triple pattern given a SPARQL query?
Posted by Andy Seaborne <an...@apache.org>.
On 02/02/16 19:29, Paul Houle wrote:
> Carlo, Andy,
>
> I like the Iterator<> interfaces in the Jena framework for getting data
> out, but I make a habit of always putting results in a List or Queue or
> something before putting them back into the same Jena model because i get
> less BS per mile that way in terms of Exceptions and other exceptional
> events.
>
> Does Jena have an official policy on being reenterable in that way?
Carlo's issues are nothing to do with iterator policy.
Carlo - Use arg1 else you will not see your changes so far.
In
public Element transform(ElementGroup arg0, List<Element> arg1)
arg0 is the element from the AST before modification and
arg1 is the new elements to go in after modification by lower levels of
the bottom-up rewrite.
So if you rewrite a ElementFilter by making a new one, it will appear in
arg1 not in arg0.
Do not modify the Element* arguments in place.
See ElementTransformCopyBase
The default implementation is:
@Override
public Element transform(ElementGroup el, List<Element> elts) {
if ( el.getElements() == elts )
return el ;
ElementGroup el2 = new ElementGroup() ;
el2.getElements().addAll(elts) ;
return el2 ;
}
i.e if any change, detected by being not the exact identical list, then
do a copy of the structure. This saves object churn.
Andy
>
> On Tue, Feb 2, 2016 at 2:13 PM, Carlo.Allocca <ca...@open.ac.uk>
> wrote:
>
>>
>> Dear Andy and All,
>>
>> while I was extending and testing the code that I wrote so far concerning
>> the removing a triple from a given SPARQL query,
>> I realised that I get different outputs depending on how I start the
>> implementation of the public Element transform(ElementGroup arg0,
>> List<Element> arg1).
>> In particular, if I start with (1) I obtain some results, if I start with
>> (2) I obtain something different (you can see below the details).
>>
>> I have also used ElementTransformCleanGroupsOfOne when ElementGroup is
>> empty
>> ElementTransform transform = new
>> ElementTransformCleanGroupsOfOne();
>> Element el2 = ElementTransformer.transform(eg, transform);
>> return el2;
>>
>> but no difference in results. I am sure I am doing something wrong.
>> Moreover, my questions are: what is the main difference between the two
>> approaches? and when I should use ElementGroup arg0 and when List<Element>
>> arg1?
>>
>>
>> (1) public Element transform(ElementGroup arg0, List<Element> arg1) {
>> List<Element> elemList = arg0.getElements();
>> Iterator<Element> itr = elemList.iterator();
>> while (itr.hasNext()) {
>>
>>
>> }
>> …
>> …
>> }
>>
>>
>> (2) public Element transform(ElementGroup arg0, List<Element> arg1) {
>>
>>
>>
>> Iterator<Element> itr = arg1.iterator();
>> while (itr.hasNext()) {
>>
>>
>> }
>> …
>> …
>> }
>>
>> I know that it may be related to the little knowledge about Jena.
>> Many Thanks in advice for your clarification on the above.
>>
>> Best Regards,
>> Carlo
>>
>>
>> =======
>>
>> Below, I reported the used code (at very bottom), the two used scenario
>> with test-cases and results. In practice, you can notice that:
>>
>>
>>
>> ==== TESTING:
>>
>> Scenario A:
>>
>> public Element transform(ElementGroup arg0, List<Element> arg1) {
>>
>>
>>
>> List<Element> elemList = arg0.getElements();
>> Iterator<Element> itr = elemList.iterator();
>> while (itr.hasNext()) {
>>
>>
>> }
>> …
>> …
>> }
>>
>>
>> Test 1:
>>
>> The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
>>
>> =========== BEFORE Q1
>>
>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>>
>> SELECT DISTINCT ?name ?mbox
>> WHERE
>> { ?x foaf:name ?name
>> OPTIONAL
>> { ?x foaf:mbox ?mbox }
>> }
>>
>>
>> ============= AFTER Q1
>>
>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>>
>> SELECT DISTINCT ?name ?mbox
>> WHERE
>> { ?x foaf:name ?name }
>>
>>
>> Test2:
>>
>> The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
>> query Q2:
>>
>>
>>
>> =========== BEFORE Q2
>>
>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>
>> SELECT DISTINCT ?ind ?boss ?g
>> WHERE
>> { { ?ind rdf:type ?z
>> OPTIONAL
>> { ?boss1 ex:isBossOf1 ?ind }
>> }
>> UNION
>> { { ?boss ex:isBossOf1 ?ind }
>> UNION
>> { ?boss ex:isBossOf ?ind
>> FILTER ( ?boss = "mathieu" )
>> }
>> }
>> }
>>
>> ============= AFTER Q2: it does not remove the triple.
>>
>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>
>> SELECT DISTINCT ?ind ?boss ?g
>> WHERE
>> { { ?ind rdf:type ?z }
>> UNION
>> { { ?boss ex:isBossOf1 ?ind }
>> UNION
>> { ?boss ex:isBossOf ?ind
>> FILTER ( ?boss = "mathieu" )
>> }
>> }
>> }
>>
>>
>> Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
>> Q3:
>>
>> =========== BEFORE Q3:
>>
>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>
>> SELECT DISTINCT ?ind ?boss ?g
>> WHERE
>> { ?ind rdf:type ?z
>> FILTER ( ?ind = "mathieu" )
>> }
>>
>> ============= AFTER Q3: There is still an empty BGP present.
>>
>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>
>> SELECT DISTINCT ?ind ?boss ?g
>> WHERE
>> { # Empty BGP
>>
>>
>>
>> }
>>
>>
>>
>>
>>
>>
>>
>>
>> Scenario B:
>>
>> public Element transform(ElementGroup arg0, List<Element> arg1) {
>>
>>
>>
>> Iterator<Element> itr = arg1.iterator();
>> while (itr.hasNext()) {
>>
>>
>> }
>> …
>> …
>> }
>>
>>
>> Test 1:
>>
>> The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
>>
>> =========== BEFORE Q1
>>
>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>>
>> SELECT DISTINCT ?name ?mbox
>> WHERE
>> { ?x foaf:name ?name
>> OPTIONAL
>> { ?x foaf:mbox ?mbox }
>> }
>>
>>
>> ============= AFTER Q1: there is still the OPTION (with a ElementGroup
>> empty) clause.
>>
>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>>
>> SELECT DISTINCT ?name ?mbox
>> WHERE
>> { ?x foaf:name ?name
>> OPTIONAL
>> { # Empty BGP
>>
>>
>>
>> }
>> }
>>
>>
>>
>>
>> Test 2:
>>
>> The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
>> query Q2:
>>
>>
>>
>> =========== BEFORE Q2
>>
>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>
>> SELECT DISTINCT ?ind ?boss ?g
>> WHERE
>> { { ?ind rdf:type ?z
>> OPTIONAL
>> { ?boss1 ex:isBossOf1 ?ind }
>> }
>> UNION
>> { { ?boss ex:isBossOf1 ?ind }
>> UNION
>> { ?boss ex:isBossOf ?ind
>> FILTER ( ?boss = "mathieu" )
>> }
>> }
>> }
>>
>> ============= AFTER Q2: it does not remove the OPTION and it leaves an
>> empty BGP.
>>
>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>
>> SELECT DISTINCT ?ind ?boss ?g
>> WHERE
>> { { ?ind rdf:type ?z
>> OPTIONAL
>> { # Empty BGP
>>
>>
>>
>> }
>> }
>> UNION
>> { { ?boss ex:isBossOf1 ?ind }
>> UNION
>> { ?boss ex:isBossOf ?ind
>> FILTER ( ?boss = "mathieu" )
>> }
>> }
>> }
>>
>> Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
>> Q3:
>>
>> =========== BEFORE Q3
>>
>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>
>> SELECT DISTINCT ?ind ?boss ?g
>> WHERE
>> { ?ind rdf:type ?z
>> FILTER ( ?ind = "mathieu" )
>> }
>>
>> ============= AFTER Q3: It does not remove the FILTER, but just the triple.
>>
>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>
>> SELECT DISTINCT ?ind ?boss ?g
>> WHERE
>> { { ?ind rdf:type ?z }
>> UNION
>> { # Empty BGP
>>
>>
>>
>> FILTER ( ?boss = "mathieu" )
>> }
>> }
>>
>>
>>
>>
>>
>>
>>
>> === FULL CODE used with public Element transform(ElementPathBlock
>> eltPB)
>>
>> @Override
>> public Element transform(ElementPathBlock eltPB) {
>> if (eltPB.isEmpty()) {
>>
>> //System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
>> ElementPathBlock IS EMPTY:: " + eltPB.toString());
>> return eltPB;
>> }
>> System.out.println("[RemoveOpTransform::transform(ElementPathBlock
>> arg0)] ElementPathBlock:: " + eltPB.toString());
>> Iterator<TriplePath> l = eltPB.patternElts();
>> while (l.hasNext()) {
>> TriplePath tp = l.next();
>> if (tp.asTriple().matches(this.triple)) {
>> l.remove();
>>
>> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
>> ElementPathBlock:: " + tp.toString() + " TRIPLE JUST REMOVED!!!");
>>
>> //System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
>> TRIPLE JUST REMOVED!!! ");
>> System.out.println("");
>> return this.transform(eltPB);//eltPB;
>> }
>> }
>> return eltPB;
>> }
>>
>>
>> === FULL CODE used with public Element transform(ElementGroup arg0,
>> List<Element> arg1)
>>
>> @Override
>> public Element transform(ElementGroup arg0, List<Element> arg1) {
>>
>>
>>
>> List<Element> elemList = arg0.getElements();
>> Iterator<Element> itr = elemList.iterator();
>> //Iterator<Element> itr = arg1.iterator();
>> while (itr.hasNext()) {
>> Element elem = itr.next();
>> if (elem instanceof ElementOptional) {
>> boolean isElementOptionalEmpty =
>> isElementOptionalEmpty((ElementOptional) elem);
>> if (isElementOptionalEmpty) {
>> itr.remove();
>> }
>> }
>>
>> else if (elem instanceof ElementGroup) {
>> boolean isElementGroupEmpty =
>> isElementGroupEmpty((ElementGroup) elem);
>> if (isElementGroupEmpty) {
>> itr.remove();
>> }
>> }
>> else if (elem instanceof ElementFilter) {
>> //... check if this filter is the one that we should remove
>> //...get the variables of the triple pattern that we want
>> to delete
>> Set<Var> tpVars = new HashSet();
>> Node subj = this.triple.getSubject();
>> if (subj.isVariable()) {
>> tpVars.add((Var) subj);
>> }
>> Node pred = this.triple.getPredicate();
>> if (pred.isVariable()) {
>> tpVars.add((Var) pred);
>> }
>> Node obj = this.triple.getObject();
>> if (obj.isVariable()) {
>> tpVars.add((Var) obj);
>> }
>> //...get the variables of the FILTER expression
>> Set<Var> expVars = ((ElementFilter)
>> elem).getExpr().getVarsMentioned();
>> //...check whether the FILTER expression contains any of
>> the triple pattern variable
>> for (Var var : expVars) {
>> //..if it does then we have to delete the entire
>> FILTER expression
>> if (tpVars.contains(var)) {
>> itr.remove();
>> }
>> }
>> }
>> else if (elem instanceof ElementUnion) {
>> boolean isUnionBothSidesEmpty =
>> isUnionBothSidesEmpty1((ElementUnion) elem);
>> if (isUnionBothSidesEmpty) {
>> itr.remove();
>> }
>> }
>>
>> }
>> return arg0;
>> }
>>
>>
>>
>>
>>
>>
>>
>>
>> On 2 Feb 2016, at 10:54, Carlo.Allocca <carlo.allocca@open.ac.uk<mailto:
>> carlo.allocca@open.ac.uk>> wrote:
>>
>> Dear Andy,
>>
>> Thank you for your time. Very appreciated.
>> Some comments follow in lines.
>>
>> On 2 Feb 2016, at 09:36, Andy Seaborne <andy@apache.org<mailto:
>> andy@apache.org>> wrote:
>>
>>
>> when removing the triple (?boss ex:isBossOf ?ind .”), I get
>>
>> SELECT DISTINCT ?ind ?boss ?g
>> WHERE
>> { { ?ind rdf:type ?z }
>> UNION
>> { { ?boss ex:isBossOf1 ?ind }
>> UNION
>> { # Empty BGP
>>
>> }
>> }
>> }
>>
>> which is OK.
>> I just need to find out how to remove an ElementGroup which contains only
>> one element which is the EMPTY one.
>> Of course, I need to do the same for the other case, e.g. OPTION,
>> SUBquery, etc.
>>
>> Do note that evaluating {} (empty syntax group) yields one row of zero
>> columns - it contributes to the overall results (it's the join identity).
>>
>> I see. To avoid this I am going to apply a
>> ElementTransformCleanGroupsOfOne as you suggested.
>>
>>
>> Now you have to look at all the elements that have a group in
>> ElementUnion, ElementOptional, ElementMinus, …
>> Yes, I need to cover all the SPARQL language from the “public Element
>> transform(ElementGroup arg0, List<Element> arg1)” call.
>> At least this is my understanding so far.
>>
>>
>>
>> That is what ElementTransformCleanGroupsOfOne does, except it looks for
>> "groups of one"
>>
>> .. UNION { { stuff } }
>>
>> and isn't to fussy about finding them all (it's an optimization, more a
>> tidying of the tree, not a change in the effect of a query which is what
>> removing triple patterns is).
>>
>> And of course changes from the bottom could potentially cause change all
>> the way up to the top of the syntax tree.
>>
>> also: they maybe be original, legal empty groups in the tree.
>>
>> Thanks for the detailed clarifications. Indeed, I will consider them.
>>
>> Many Thanks,
>> Best Regards,
>> Carlo
>>
>>
>>
>> Andy
>>
>>
>>
>>
>>
>>
>> -- The Open University is incorporated by Royal Charter (RC 000391), an
>> exempt charity in England & Wales and a charity registered in Scotland (SC
>> 038302). The Open University is authorised and regulated by the Financial
>> Conduct Authority.
>>
>>
>
>
Re: How to remove consistently a triple pattern given a SPARQL query?
Posted by Paul Houle <on...@gmail.com>.
Carlo, Andy,
I like the Iterator<> interfaces in the Jena framework for getting data
out, but I make a habit of always putting results in a List or Queue or
something before putting them back into the same Jena model because i get
less BS per mile that way in terms of Exceptions and other exceptional
events.
Does Jena have an official policy on being reenterable in that way?
On Tue, Feb 2, 2016 at 2:13 PM, Carlo.Allocca <ca...@open.ac.uk>
wrote:
>
> Dear Andy and All,
>
> while I was extending and testing the code that I wrote so far concerning
> the removing a triple from a given SPARQL query,
> I realised that I get different outputs depending on how I start the
> implementation of the public Element transform(ElementGroup arg0,
> List<Element> arg1).
> In particular, if I start with (1) I obtain some results, if I start with
> (2) I obtain something different (you can see below the details).
>
> I have also used ElementTransformCleanGroupsOfOne when ElementGroup is
> empty
> ElementTransform transform = new
> ElementTransformCleanGroupsOfOne();
> Element el2 = ElementTransformer.transform(eg, transform);
> return el2;
>
> but no difference in results. I am sure I am doing something wrong.
> Moreover, my questions are: what is the main difference between the two
> approaches? and when I should use ElementGroup arg0 and when List<Element>
> arg1?
>
>
> (1) public Element transform(ElementGroup arg0, List<Element> arg1) {
> List<Element> elemList = arg0.getElements();
> Iterator<Element> itr = elemList.iterator();
> while (itr.hasNext()) {
>
>
> }
> …
> …
> }
>
>
> (2) public Element transform(ElementGroup arg0, List<Element> arg1) {
>
>
>
> Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
>
>
> }
> …
> …
> }
>
> I know that it may be related to the little knowledge about Jena.
> Many Thanks in advice for your clarification on the above.
>
> Best Regards,
> Carlo
>
>
> =======
>
> Below, I reported the used code (at very bottom), the two used scenario
> with test-cases and results. In practice, you can notice that:
>
>
>
> ==== TESTING:
>
> Scenario A:
>
> public Element transform(ElementGroup arg0, List<Element> arg1) {
>
>
>
> List<Element> elemList = arg0.getElements();
> Iterator<Element> itr = elemList.iterator();
> while (itr.hasNext()) {
>
>
> }
> …
> …
> }
>
>
> Test 1:
>
> The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
>
> =========== BEFORE Q1
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>
> SELECT DISTINCT ?name ?mbox
> WHERE
> { ?x foaf:name ?name
> OPTIONAL
> { ?x foaf:mbox ?mbox }
> }
>
>
> ============= AFTER Q1
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>
> SELECT DISTINCT ?name ?mbox
> WHERE
> { ?x foaf:name ?name }
>
>
> Test2:
>
> The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
> query Q2:
>
>
>
> =========== BEFORE Q2
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z
> OPTIONAL
> { ?boss1 ex:isBossOf1 ?ind }
> }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
> }
>
> ============= AFTER Q2: it does not remove the triple.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
> }
>
>
> Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
> Q3:
>
> =========== BEFORE Q3:
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { ?ind rdf:type ?z
> FILTER ( ?ind = "mathieu" )
> }
>
> ============= AFTER Q3: There is still an empty BGP present.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { # Empty BGP
>
>
>
> }
>
>
>
>
>
>
>
>
> Scenario B:
>
> public Element transform(ElementGroup arg0, List<Element> arg1) {
>
>
>
> Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
>
>
> }
> …
> …
> }
>
>
> Test 1:
>
> The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
>
> =========== BEFORE Q1
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>
> SELECT DISTINCT ?name ?mbox
> WHERE
> { ?x foaf:name ?name
> OPTIONAL
> { ?x foaf:mbox ?mbox }
> }
>
>
> ============= AFTER Q1: there is still the OPTION (with a ElementGroup
> empty) clause.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> PREFIX foaf: <http://xmlns.com/foaf/0.1/>
>
> SELECT DISTINCT ?name ?mbox
> WHERE
> { ?x foaf:name ?name
> OPTIONAL
> { # Empty BGP
>
>
>
> }
> }
>
>
>
>
> Test 2:
>
> The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below
> query Q2:
>
>
>
> =========== BEFORE Q2
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z
> OPTIONAL
> { ?boss1 ex:isBossOf1 ?ind }
> }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
> }
>
> ============= AFTER Q2: it does not remove the OPTION and it leaves an
> empty BGP.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z
> OPTIONAL
> { # Empty BGP
>
>
>
> }
> }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
> }
>
> Test 3: The triple to remove is (?ind rdf:type ?z) using the below query
> Q3:
>
> =========== BEFORE Q3
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { ?ind rdf:type ?z
> FILTER ( ?ind = "mathieu" )
> }
>
> ============= AFTER Q3: It does not remove the FILTER, but just the triple.
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { # Empty BGP
>
>
>
> FILTER ( ?boss = "mathieu" )
> }
> }
>
>
>
>
>
>
>
> === FULL CODE used with public Element transform(ElementPathBlock
> eltPB)
>
> @Override
> public Element transform(ElementPathBlock eltPB) {
> if (eltPB.isEmpty()) {
>
> //System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
> ElementPathBlock IS EMPTY:: " + eltPB.toString());
> return eltPB;
> }
> System.out.println("[RemoveOpTransform::transform(ElementPathBlock
> arg0)] ElementPathBlock:: " + eltPB.toString());
> Iterator<TriplePath> l = eltPB.patternElts();
> while (l.hasNext()) {
> TriplePath tp = l.next();
> if (tp.asTriple().matches(this.triple)) {
> l.remove();
>
> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
> ElementPathBlock:: " + tp.toString() + " TRIPLE JUST REMOVED!!!");
>
> //System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)]
> TRIPLE JUST REMOVED!!! ");
> System.out.println("");
> return this.transform(eltPB);//eltPB;
> }
> }
> return eltPB;
> }
>
>
> === FULL CODE used with public Element transform(ElementGroup arg0,
> List<Element> arg1)
>
> @Override
> public Element transform(ElementGroup arg0, List<Element> arg1) {
>
>
>
> List<Element> elemList = arg0.getElements();
> Iterator<Element> itr = elemList.iterator();
> //Iterator<Element> itr = arg1.iterator();
> while (itr.hasNext()) {
> Element elem = itr.next();
> if (elem instanceof ElementOptional) {
> boolean isElementOptionalEmpty =
> isElementOptionalEmpty((ElementOptional) elem);
> if (isElementOptionalEmpty) {
> itr.remove();
> }
> }
>
> else if (elem instanceof ElementGroup) {
> boolean isElementGroupEmpty =
> isElementGroupEmpty((ElementGroup) elem);
> if (isElementGroupEmpty) {
> itr.remove();
> }
> }
> else if (elem instanceof ElementFilter) {
> //... check if this filter is the one that we should remove
> //...get the variables of the triple pattern that we want
> to delete
> Set<Var> tpVars = new HashSet();
> Node subj = this.triple.getSubject();
> if (subj.isVariable()) {
> tpVars.add((Var) subj);
> }
> Node pred = this.triple.getPredicate();
> if (pred.isVariable()) {
> tpVars.add((Var) pred);
> }
> Node obj = this.triple.getObject();
> if (obj.isVariable()) {
> tpVars.add((Var) obj);
> }
> //...get the variables of the FILTER expression
> Set<Var> expVars = ((ElementFilter)
> elem).getExpr().getVarsMentioned();
> //...check whether the FILTER expression contains any of
> the triple pattern variable
> for (Var var : expVars) {
> //..if it does then we have to delete the entire
> FILTER expression
> if (tpVars.contains(var)) {
> itr.remove();
> }
> }
> }
> else if (elem instanceof ElementUnion) {
> boolean isUnionBothSidesEmpty =
> isUnionBothSidesEmpty1((ElementUnion) elem);
> if (isUnionBothSidesEmpty) {
> itr.remove();
> }
> }
>
> }
> return arg0;
> }
>
>
>
>
>
>
>
>
> On 2 Feb 2016, at 10:54, Carlo.Allocca <carlo.allocca@open.ac.uk<mailto:
> carlo.allocca@open.ac.uk>> wrote:
>
> Dear Andy,
>
> Thank you for your time. Very appreciated.
> Some comments follow in lines.
>
> On 2 Feb 2016, at 09:36, Andy Seaborne <andy@apache.org<mailto:
> andy@apache.org>> wrote:
>
>
> when removing the triple (?boss ex:isBossOf ?ind .”), I get
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { # Empty BGP
>
> }
> }
> }
>
> which is OK.
> I just need to find out how to remove an ElementGroup which contains only
> one element which is the EMPTY one.
> Of course, I need to do the same for the other case, e.g. OPTION,
> SUBquery, etc.
>
> Do note that evaluating {} (empty syntax group) yields one row of zero
> columns - it contributes to the overall results (it's the join identity).
>
> I see. To avoid this I am going to apply a
> ElementTransformCleanGroupsOfOne as you suggested.
>
>
> Now you have to look at all the elements that have a group in
> ElementUnion, ElementOptional, ElementMinus, …
> Yes, I need to cover all the SPARQL language from the “public Element
> transform(ElementGroup arg0, List<Element> arg1)” call.
> At least this is my understanding so far.
>
>
>
> That is what ElementTransformCleanGroupsOfOne does, except it looks for
> "groups of one"
>
> .. UNION { { stuff } }
>
> and isn't to fussy about finding them all (it's an optimization, more a
> tidying of the tree, not a change in the effect of a query which is what
> removing triple patterns is).
>
> And of course changes from the bottom could potentially cause change all
> the way up to the top of the syntax tree.
>
> also: they maybe be original, legal empty groups in the tree.
>
> Thanks for the detailed clarifications. Indeed, I will consider them.
>
> Many Thanks,
> Best Regards,
> Carlo
>
>
>
> Andy
>
>
>
>
>
>
> -- The Open University is incorporated by Royal Charter (RC 000391), an
> exempt charity in England & Wales and a charity registered in Scotland (SC
> 038302). The Open University is authorised and regulated by the Financial
> Conduct Authority.
>
>
--
Paul Houle
*Applying Schemas for Natural Language Processing, Distributed Systems,
Classification and Text Mining and Data Lakes*
(607) 539 6254 paul.houle on Skype ontology2@gmail.com
:BaseKB -- Query Freebase Data With SPARQL
http://basekb.com/gold/
Legal Entity Identifier Lookup
https://legalentityidentifier.info/lei/lookup/
<http://legalentityidentifier.info/lei/lookup/>
Join our Data Lakes group on LinkedIn
https://www.linkedin.com/grp/home?gid=8267275
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Dear Andy and All,
while I was extending and testing the code that I wrote so far concerning the removing a triple from a given SPARQL query,
I realised that I get different outputs depending on how I start the implementation of the public Element transform(ElementGroup arg0, List<Element> arg1).
In particular, if I start with (1) I obtain some results, if I start with (2) I obtain something different (you can see below the details).
I have also used ElementTransformCleanGroupsOfOne when ElementGroup is empty
ElementTransform transform = new ElementTransformCleanGroupsOfOne();
Element el2 = ElementTransformer.transform(eg, transform);
return el2;
but no difference in results. I am sure I am doing something wrong.
Moreover, my questions are: what is the main difference between the two approaches? and when I should use ElementGroup arg0 and when List<Element> arg1?
(1) public Element transform(ElementGroup arg0, List<Element> arg1) {
List<Element> elemList = arg0.getElements();
Iterator<Element> itr = elemList.iterator();
while (itr.hasNext()) {
}
…
…
}
(2) public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
}
…
…
}
I know that it may be related to the little knowledge about Jena.
Many Thanks in advice for your clarification on the above.
Best Regards,
Carlo
=======
Below, I reported the used code (at very bottom), the two used scenario with test-cases and results. In practice, you can notice that:
==== TESTING:
Scenario A:
public Element transform(ElementGroup arg0, List<Element> arg1) {
List<Element> elemList = arg0.getElements();
Iterator<Element> itr = elemList.iterator();
while (itr.hasNext()) {
}
…
…
}
Test 1:
The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
=========== BEFORE Q1
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name
OPTIONAL
{ ?x foaf:mbox ?mbox }
}
============= AFTER Q1
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name }
Test2:
The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below query Q2:
=========== BEFORE Q2
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z
OPTIONAL
{ ?boss1 ex:isBossOf1 ?ind }
}
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
============= AFTER Q2: it does not remove the triple.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
Test 3: The triple to remove is (?ind rdf:type ?z) using the below query Q3:
=========== BEFORE Q3:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ ?ind rdf:type ?z
FILTER ( ?ind = "mathieu" )
}
============= AFTER Q3: There is still an empty BGP present.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ # Empty BGP
}
Scenario B:
public Element transform(ElementGroup arg0, List<Element> arg1) {
Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
}
…
…
}
Test 1:
The triple to remove is (?x foaf:mbox ?mbox ) using the below query Q1:
=========== BEFORE Q1
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name
OPTIONAL
{ ?x foaf:mbox ?mbox }
}
============= AFTER Q1: there is still the OPTION (with a ElementGroup empty) clause.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?mbox
WHERE
{ ?x foaf:name ?name
OPTIONAL
{ # Empty BGP
}
}
Test 2:
The triple to remove is (?boss1 ex:isBossOf1 ?ind ) using the below query Q2:
=========== BEFORE Q2
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z
OPTIONAL
{ ?boss1 ex:isBossOf1 ?ind }
}
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
============= AFTER Q2: it does not remove the OPTION and it leaves an empty BGP.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z
OPTIONAL
{ # Empty BGP
}
}
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
}
Test 3: The triple to remove is (?ind rdf:type ?z) using the below query Q3:
=========== BEFORE Q3
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ ?ind rdf:type ?z
FILTER ( ?ind = "mathieu" )
}
============= AFTER Q3: It does not remove the FILTER, but just the triple.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ # Empty BGP
FILTER ( ?boss = "mathieu" )
}
}
=== FULL CODE used with public Element transform(ElementPathBlock eltPB)
@Override
public Element transform(ElementPathBlock eltPB) {
if (eltPB.isEmpty()) {
//System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] ElementPathBlock IS EMPTY:: " + eltPB.toString());
return eltPB;
}
System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] ElementPathBlock:: " + eltPB.toString());
Iterator<TriplePath> l = eltPB.patternElts();
while (l.hasNext()) {
TriplePath tp = l.next();
if (tp.asTriple().matches(this.triple)) {
l.remove();
System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] ElementPathBlock:: " + tp.toString() + " TRIPLE JUST REMOVED!!!");
//System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] TRIPLE JUST REMOVED!!! ");
System.out.println("");
return this.transform(eltPB);//eltPB;
}
}
return eltPB;
}
=== FULL CODE used with public Element transform(ElementGroup arg0, List<Element> arg1)
@Override
public Element transform(ElementGroup arg0, List<Element> arg1) {
List<Element> elemList = arg0.getElements();
Iterator<Element> itr = elemList.iterator();
//Iterator<Element> itr = arg1.iterator();
while (itr.hasNext()) {
Element elem = itr.next();
if (elem instanceof ElementOptional) {
boolean isElementOptionalEmpty = isElementOptionalEmpty((ElementOptional) elem);
if (isElementOptionalEmpty) {
itr.remove();
}
}
else if (elem instanceof ElementGroup) {
boolean isElementGroupEmpty = isElementGroupEmpty((ElementGroup) elem);
if (isElementGroupEmpty) {
itr.remove();
}
}
else if (elem instanceof ElementFilter) {
//... check if this filter is the one that we should remove
//...get the variables of the triple pattern that we want to delete
Set<Var> tpVars = new HashSet();
Node subj = this.triple.getSubject();
if (subj.isVariable()) {
tpVars.add((Var) subj);
}
Node pred = this.triple.getPredicate();
if (pred.isVariable()) {
tpVars.add((Var) pred);
}
Node obj = this.triple.getObject();
if (obj.isVariable()) {
tpVars.add((Var) obj);
}
//...get the variables of the FILTER expression
Set<Var> expVars = ((ElementFilter) elem).getExpr().getVarsMentioned();
//...check whether the FILTER expression contains any of the triple pattern variable
for (Var var : expVars) {
//..if it does then we have to delete the entire FILTER expression
if (tpVars.contains(var)) {
itr.remove();
}
}
}
else if (elem instanceof ElementUnion) {
boolean isUnionBothSidesEmpty = isUnionBothSidesEmpty1((ElementUnion) elem);
if (isUnionBothSidesEmpty) {
itr.remove();
}
}
}
return arg0;
}
On 2 Feb 2016, at 10:54, Carlo.Allocca <ca...@open.ac.uk>> wrote:
Dear Andy,
Thank you for your time. Very appreciated.
Some comments follow in lines.
On 2 Feb 2016, at 09:36, Andy Seaborne <an...@apache.org>> wrote:
when removing the triple (?boss ex:isBossOf ?ind .”), I get
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ # Empty BGP
}
}
}
which is OK.
I just need to find out how to remove an ElementGroup which contains only one element which is the EMPTY one.
Of course, I need to do the same for the other case, e.g. OPTION, SUBquery, etc.
Do note that evaluating {} (empty syntax group) yields one row of zero columns - it contributes to the overall results (it's the join identity).
I see. To avoid this I am going to apply a ElementTransformCleanGroupsOfOne as you suggested.
Now you have to look at all the elements that have a group in ElementUnion, ElementOptional, ElementMinus, …
Yes, I need to cover all the SPARQL language from the “public Element transform(ElementGroup arg0, List<Element> arg1)” call.
At least this is my understanding so far.
That is what ElementTransformCleanGroupsOfOne does, except it looks for "groups of one"
.. UNION { { stuff } }
and isn't to fussy about finding them all (it's an optimization, more a tidying of the tree, not a change in the effect of a query which is what removing triple patterns is).
And of course changes from the bottom could potentially cause change all the way up to the top of the syntax tree.
also: they maybe be original, legal empty groups in the tree.
Thanks for the detailed clarifications. Indeed, I will consider them.
Many Thanks,
Best Regards,
Carlo
Andy
-- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Dear Andy,
Thank you for your time. Very appreciated.
Some comments follow in lines.
> On 2 Feb 2016, at 09:36, Andy Seaborne <an...@apache.org> wrote:
>
>
>> when removing the triple (?boss ex:isBossOf ?ind .”), I get
>>
>> SELECT DISTINCT ?ind ?boss ?g
>> WHERE
>> { { ?ind rdf:type ?z }
>> UNION
>> { { ?boss ex:isBossOf1 ?ind }
>> UNION
>> { # Empty BGP
>>
>> }
>> }
>> }
>>
>> which is OK.
>> I just need to find out how to remove an ElementGroup which contains only one element which is the EMPTY one.
>> Of course, I need to do the same for the other case, e.g. OPTION, SUBquery, etc.
>
> Do note that evaluating {} (empty syntax group) yields one row of zero columns - it contributes to the overall results (it's the join identity).
>
I see. To avoid this I am going to apply a ElementTransformCleanGroupsOfOne as you suggested.
> Now you have to look at all the elements that have a group in ElementUnion, ElementOptional, ElementMinus, …
Yes, I need to cover all the SPARQL language from the “public Element transform(ElementGroup arg0, List<Element> arg1)” call.
At least this is my understanding so far.
>
> That is what ElementTransformCleanGroupsOfOne does, except it looks for "groups of one"
>
> .. UNION { { stuff } }
>
> and isn't to fussy about finding them all (it's an optimization, more a tidying of the tree, not a change in the effect of a query which is what removing triple patterns is).
>
> And of course changes from the bottom could potentially cause change all the way up to the top of the syntax tree.
>
> also: they maybe be original, legal empty groups in the tree.
>
Thanks for the detailed clarifications. Indeed, I will consider them.
Many Thanks,
Best Regards,
Carlo
> Andy
>
>
>
>
>
-- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Hi Martynas,
Thank you for your input.
I don’t know much about SPIN RDF.
Just to clarify: my task is not to optimise an original query.
I am working on it using Jena.
As soon as I complete the entire algorithm I will publish somewhere and share with all of you (as I am sure it can be optimised).
May Thanks,
Best Regards,
Carlo
> On 1 Feb 2016, at 22:55, Martynas Jusevičius <ma...@graphity.org> wrote:
>
> This thread got me thinking -- couldn't we have reusable,
> dereferenceable SPARQL optimizations/rewrites as SPARQL CONSTRUCTs
> over SPIN RDF? Which would be mappings between the original syntax
> tree and the optimized syntax tree.
>
> On Mon, Feb 1, 2016 at 8:55 PM, Carlo.Allocca <ca...@open.ac.uk> wrote:
>> Dear Andy, Lorenz and All,
>>
>> Thank you very much for your help and support.
>> I would like to share the first achievement based on your suggestions.
>>
>> I have implemented
>>
>> 1) public Element transform(ElementPathBlock eltPB)
>> 2) public Element transform(ElementGroup arg0, List<Element> arg1)
>>
>> running it over a number of example queries I obtain the expected results.
>> For example, for the input query
>>
>> String qString6 = "prefix rdfs:<http://www.w3.org/2000/01/rdf-schema#> "
>> + "prefix ex:<http://www.semanticweb.org/dataset1/> "
>> + "prefix rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
>> + " SELECT DISTINCT ?ind ?boss ?g where "
>> + "{ "
>> + " {?ind rdf:type ?z. } "
>> + "UNION "
>> + " {"
>> + " { ?boss ex:isBossOf1 ?ind .}"
>> + " UNION {?boss ex:isBossOf ?ind ."
>> + " Filter(?boss=\"mathieu\") }"
>> + "}"
>> + "}";
>>
>> when removing the triple (?boss ex:isBossOf ?ind .”), I get
>>
>> SELECT DISTINCT ?ind ?boss ?g
>> WHERE
>> { { ?ind rdf:type ?z }
>> UNION
>> { { ?boss ex:isBossOf1 ?ind }
>> UNION
>> { # Empty BGP
>>
>> }
>> }
>> }
>>
>> which is OK.
>> I just need to find out how to remove an ElementGroup which contains only one element which is the EMPTY one.
>> Of course, I need to do the same for the other case, e.g. OPTION, SUBquery, etc.
>>
>> Many Thanks for your help one again.
>> Best Regards,
>> Carlo
>>
>>
>>
>> == Here the code
>>
>>
>> @Override
>> public Element transform(ElementPathBlock eltPB) {
>> if (eltPB.isEmpty()) {
>> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] ElementPathBlock IS EMPTY:: " + eltPB.toString());
>> return eltPB;
>> }
>> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] ElementPathBlock:: " + eltPB.toString());
>> Iterator<TriplePath> l = eltPB.patternElts();
>> while (l.hasNext()) {
>> TriplePath tp = l.next();
>> if (tp.asTriple().matches(this.triple)) {
>> l.remove();
>> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] ElementPathBlock:: " + tp.toString()+" TRIPLE JUST REMOVED!!!");
>> //System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] TRIPLE JUST REMOVED!!! ");
>> System.out.println("");
>> return this.transform(eltPB);//eltPB;
>> }
>> }
>> return eltPB;
>> }
>>
>>
>> @Override
>> public Element transform(ElementGroup arg0, List<Element> arg1) {
>> //ElementGroup arg0New = new ElementGroup();
>>
>> List<Element> elemList = arg0.getElements();
>> Iterator<Element> itr = elemList.iterator();
>> while (itr.hasNext()) {
>> Element elem = itr.next();
>> if (elem instanceof ElementGroup) {
>> // if(((ElementGroup) elem).isEmpty()){
>> System.out.println("[RemoveOpTransform::visit(ElementGroup arg0)] ElementGroup IS EMPTY!!! " +((ElementGroup) elem).toString());
>> System.out.println("[RemoveOpTransform::visit(ElementGroup arg0)] List<Element> arg1 IS EMPTY!!! " +arg1.toString());
>> // }
>> }
>>
>> if (elem instanceof ElementFilter) {
>> //... check if this filter is the one that we should remove
>> //...get the variables of the triple pattern that we want to delete
>> Set<Var> tpVars = new HashSet();
>> Node subj = this.triple.getSubject();
>> if (subj.isVariable()) {
>> tpVars.add((Var) subj);
>> }
>> Node pred = this.triple.getPredicate();
>> if (pred.isVariable()) {
>> tpVars.add((Var) pred);
>> }
>> Node obj = this.triple.getObject();
>> if (obj.isVariable()) {
>> tpVars.add((Var) obj);
>> }
>> //...get the variables of the FILTER expression
>> Set<Var> expVars = ((ElementFilter) elem).getExpr().getVarsMentioned();
>> //...check whether the FILTER expression contains any of the triple pattern variable
>> for (Var var : expVars) {
>> //..if it does then we have to delete the entire FILTER expression
>> if (tpVars.contains(var)) {
>> System.out.println("[RemoveOpTransform::visit(ElementGroup arg0)] THE "+((ElementFilter) elem).toString() +"IS GOING TO BE REMOVED!!!");
>> //Expr e = new NodeValueBoolean(true);
>> //ElementFilter newFilter = new ElementFilter(e);
>> itr.remove();
>> return this.transform(arg0, arg1);
>> }
>> }
>>
>> }
>> }
>> // System.out.println("[RemoveOpTransform::transform(ElementGroup arg0)] arg1 " + arg1.toString());
>> // System.out.println("");
>> //return arg0New;
>> return arg0;
>> }
>>
>>
>>
>>
>>> On 31 Jan 2016, at 15:40, Carlo.Allocca <ca...@open.ac.uk> wrote:
>>>
>>> Dear Andy,
>>>
>>>
>>>> On 31 Jan 2016, at 15:25, Andy Seaborne <an...@apache.org> wrote:
>>>>
>>>> Cleaning up is slightly easier in the syntax because BGPs and filters are inside a group (nothing to do with GROUP - a syntax group is things between {}.
>>>>
>>>> So when you want to delete something, have some custom Element class 'ElementDeleteMe' to return from the ElementFilter or ElementPathBlock. Something that can not appear in a legal query. it does not need to implement anything.
>>>>
>>>> Then in
>>>> transform(ElementGroup el, List<Element> members) ;
>>>>
>>>> rewrite 'members' to remove any ElementDeleteMe.
>>>>
>>>> if members.size == 0
>>>> return ElementDeleteMe
>>>>
>>>> so it recursive works.
>>>>
>>>> Take care at the top of syntax tree.
>>>>
>>> Thank you for the details.
>>> It seems that I should be using org.apache.jena.sparql.syntax rather than org.apache.jena.sparql.algebra.
>>> I will try to implement it as suggested above.
>>>
>>> Many Thanks,
>>> Best Regards,
>>> Carlo
>>>
>>>
>>>> Andy
>>>>
>>>> On 31/01/16 15:11, Carlo.Allocca wrote:
>>>>> Hello Lorenz,
>>>>>
>>>>>
>>>>> Sure no problem.
>>>>> I can share it here. In case you have suggest any other place I will do so.
>>>>>
>>>>> Please, let me know.
>>>>> Many Thanks,
>>>>>
>>>>> Best Regards,
>>>>> Carlo
>>>>>
>>>>>> On 31 Jan 2016, at 15:07, Lorenz Bühmann <bu...@informatik.uni-leipzig.de> wrote:
>>>>>>
>>>>>> Hello Carlo,
>>>>>>
>>>>>> I'm sure you'll make it, but maybe you should also share the complete code somehow? Maybe this makes it easier for people to help you.
>>>>>>
>>>>>> Lorenz
>>>>>>
>>>>>>> Hello Lorenz,
>>>>>>>
>>>>>>> Thank you very much for your help.
>>>>>>> Some comments follow in line.
>>>>>>>
>>>>>>>
>>>>>>>> On 31 Jan 2016, at 13:36, Lorenz Bühmann <bu...@informatik.uni-leipzig.de> wrote:
>>>>>>>>
>>>>>>>> Hello Carlo,
>>>>>>>>
>>>>>>>> there is usually no link from a child node to its parent in the JENA data structures.
>>>>>>> It is very good to confirm it as I don’t spend more time to look for it. I thought that I was missing some JENA data structure and packages.
>>>>>>>
>>>>>>>> That means you have to keep track of it when you're processing the parents. Why not run some "clean up" after each child has been processed? E.g. check if there is no BGP left and thus mark this current parent as also "toBeRemoved”.
>>>>>>> Sure. I have already started doing it by using some boolean variables. Let’s see if I can make it.
>>>>>>> Otherwise I have to develop a module that transform the Jena Query Expression into a Tree based representation and then apply the triple remove operation.
>>>>>>>
>>>>>>> Thank you again for your support and answers.
>>>>>>>
>>>>>>> Best Regards,
>>>>>>> Carlo
>>>>>>>
>>>>>>>> Lorenz
>>>>>>>>
>>>>>>>>> and of course, the below is for processing an BGP:
>>>>>>>>>
>>>>>>>>> @Override
>>>>>>>>> public Op transform(OpBGP opBGP) {
>>>>>>>>>
>>>>>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter " + opBGPCounter++);
>>>>>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] " + opBGP.toString());
>>>>>>>>> System.out.println("");
>>>>>>>>> Op newOpBGP = opBGP.copy();
>>>>>>>>> BasicPattern newBP = ((OpBGP) newOpBGP).getPattern();
>>>>>>>>> List<Triple> tripleList = newBP.getList();
>>>>>>>>>
>>>>>>>>> Iterator<Triple> itr = tripleList.iterator();
>>>>>>>>> while (itr.hasNext()) {
>>>>>>>>> Triple tp = itr.next();
>>>>>>>>> if (tp.matches(this.triple)) {
>>>>>>>>> itr.remove();
>>>>>>>>> isParent = true;
>>>>>>>>> isStarted = true;
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>> //...it can be empty
>>>>>>>>> if (((OpBGP) newOpBGP).getPattern().getList().isEmpty()) {
>>>>>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty " + opBGP.toString());
>>>>>>>>> //return subOp;
>>>>>>>>> }
>>>>>>>>> return newOpBGP;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Many Thanks,
>>>>>>>>> Carlo.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>> On 31 Jan 2016, at 04:36, Carlo.Allocca <ca...@open.ac.uk> wrote:
>>>>>>>>>>
>>>>>>>>>> Dear Andy,
>>>>>>>>>>
>>>>>>>>>> Thank you very much one more time.
>>>>>>>>>>
>>>>>>>>>> Please, some comments follow in line.
>>>>>>>>>>
>>>>>>>>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>>>>>>>>
>>>>>>>>>> On 30/01/16 15:52, Carlo.Allocca wrote:
>>>>>>>>>> Hello Lorenz,
>>>>>>>>>>
>>>>>>>>>> Thank you for your help.
>>>>>>>>>>
>>>>>>>>>> It was clear to me that I have to remove from the parent expression and such is that using a patter-based approach
>>>>>>>>>> make it a bit difficult. I tried three of them and I got to the same results.
>>>>>>>>>>
>>>>>>>>>> You need to process the parent, not just the ElementFilter.
>>>>>>>>>>
>>>>>>>>>> How can I process the parent?
>>>>>>>>>> My understanding is:
>>>>>>>>>>
>>>>>>>>>> 1. Building the Abstract Query Tree: Op op = Algebra.compile(q);
>>>>>>>>>>
>>>>>>>>>> For example, given the query
>>>>>>>>>>
>>>>>>>>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>>>>>>>>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>>>>>>>>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>>>>>>>>>
>>>>>>>>>> SELECT DISTINCT ?ind ?boss ?g
>>>>>>>>>> WHERE
>>>>>>>>>> { { ?ind rdf:type ?z }
>>>>>>>>>> UNION
>>>>>>>>>> { ?boss ex:isBossOf ?ind
>>>>>>>>>> FILTER ( ?boss = "mathieu" )
>>>>>>>>>> }
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> I obtain
>>>>>>>>>>
>>>>>>>>>> (distinct
>>>>>>>>>> (project (?ind ?boss ?g)
>>>>>>>>>> (union
>>>>>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>>>> (filter (= ?boss "mathieu")
>>>>>>>>>> (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))))))
>>>>>>>>>>
>>>>>>>>>> 2) Travere the tree to modify its internal structure. In terms of code, I can write:
>>>>>>>>>>
>>>>>>>>>> (A) Transform transform = new TransformRemoveOp(q,tp) ;
>>>>>>>>>> (B) op = Transformer.transform(transform, op);
>>>>>>>>>>
>>>>>>>>>> where TransformRemoveOp implements Transform interface.
>>>>>>>>>> It seems that there is no link between children and parent that can be used to figure out at which level the process is and modify the Tree structure, accordingly. Please correct me if I am wrong.
>>>>>>>>>> In fact running it over the above example, I got the following:
>>>>>>>>>>
>>>>>>>>>> =========== DURING
>>>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 1
>>>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 2
>>>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty (bgp
>>>>>>>>>> )
>>>>>>>>>>
>>>>>>>>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter (filter (= ?boss "mathieu")
>>>>>>>>>> (bgp
>>>>>>>>>> ))
>>>>>>>>>>
>>>>>>>>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name bgp
>>>>>>>>>>
>>>>>>>>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] left: (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>>>>
>>>>>>>>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] right: (filter (exprlist (= ?boss "mathieu") true)
>>>>>>>>>> (bgp
>>>>>>>>>> ))
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> [TransformRemoveOp::transform(OpProject opProject, Op subOp)] (project (?ind ?boss ?g)
>>>>>>>>>> (union
>>>>>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>>>> (filter (exprlist (= ?boss "mathieu") true)
>>>>>>>>>> (bgp
>>>>>>>>>> ))))
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> [TransformRemoveOp::transform(OpDistinct opDistinct, Op subOp)] (distinct
>>>>>>>>>> (project (?ind ?boss ?g)
>>>>>>>>>> (union
>>>>>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>>>> (filter (exprlist (= ?boss "mathieu") true)
>>>>>>>>>> (bgp
>>>>>>>>>> )))))
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Moreover, implementing a first version of the OpFilter as reported below:
>>>>>>>>>>
>>>>>>>>>> @Override
>>>>>>>>>> public Op transform(OpFilter opFilter, Op subOp) {
>>>>>>>>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter " + opFilter.toString());
>>>>>>>>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name " + subOp.getName());
>>>>>>>>>> System.out.println("");
>>>>>>>>>>
>>>>>>>>>> if (isParent == false) {
>>>>>>>>>> return opFilter;
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> //...get the variables of the triple pattern that we want to delete
>>>>>>>>>> Set<Var> tpVars = new HashSet();
>>>>>>>>>> Node subj = this.triple.getSubject();
>>>>>>>>>> if (subj.isVariable()) {
>>>>>>>>>> tpVars.add((Var) subj);
>>>>>>>>>> }
>>>>>>>>>> Node pred = this.triple.getPredicate();
>>>>>>>>>> if (pred.isVariable()) {
>>>>>>>>>> tpVars.add((Var) pred);
>>>>>>>>>> }
>>>>>>>>>> Node obj = this.triple.getObject();
>>>>>>>>>> if (obj.isVariable()) {
>>>>>>>>>> tpVars.add((Var) obj);
>>>>>>>>>> }
>>>>>>>>>> //...get the variables of the FILTER expression
>>>>>>>>>> Op opNew = opFilter.copy(subOp);
>>>>>>>>>> Set<Var> expVars = ((OpFilter) opNew).getExprs().getVarsMentioned();
>>>>>>>>>>
>>>>>>>>>> //...check whether the FILTER expression contains any of the triple pattern variable
>>>>>>>>>> boolean isContained = false;
>>>>>>>>>> for (Var var : expVars) {
>>>>>>>>>> //..if it does then we have to delete the entire FILTER expression
>>>>>>>>>> if (tpVars.contains(var)) {
>>>>>>>>>> isContained = true;
>>>>>>>>>> break;
>>>>>>>>>> }
>>>>>>>>>> }
>>>>>>>>>> //... if the filter contains any variable of the triple that has been removed, then....
>>>>>>>>>> if (isContained) {
>>>>>>>>>> Op newOP;
>>>>>>>>>> Expr e;
>>>>>>>>>> if (subOp instanceof OpBGP) {
>>>>>>>>>> if (((OpBGP) subOp).getPattern().getList().isEmpty()) {
>>>>>>>>>> e = new NodeValueBoolean(true);
>>>>>>>>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>>>>>>>>> return newOP;
>>>>>>>>>> } else {
>>>>>>>>>> e = new NodeValueBoolean(false);
>>>>>>>>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>>>>>>>>> return newOP;
>>>>>>>>>> }
>>>>>>>>>> }
>>>>>>>>>> }
>>>>>>>>>> return opFilter;
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> It produces the following SPARQL query:
>>>>>>>>>>
>>>>>>>>>> SELECT DISTINCT ?ind ?boss ?g
>>>>>>>>>> WHERE
>>>>>>>>>> { { ?ind a ?z }
>>>>>>>>>> UNION
>>>>>>>>>> { # Empty BGP
>>>>>>>>>>
>>>>>>>>>> FILTER ( ?boss = "mathieu" )
>>>>>>>>>> FILTER ( true )
>>>>>>>>>> }
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> It seems quite challenging even transform the expression of "?boss = “mathieu” into “true” (as reported above) does not work as It should.
>>>>>>>>>>
>>>>>>>>>> If anyone could help me who is more experienced with this kind of task, I would be very very grateful.
>>>>>>>>>> I would like to see something concrete in sense of line of code as I am using.
>>>>>>>>>>
>>>>>>>>>> Many Thanks,
>>>>>>>>>> Best Regards,
>>>>>>>>>> Carlo
>>>>>>>>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>>>>>>>>
>>>>>>>>>> element has active parts
>>>>>>>>>>
>>>>>>>>>> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>>>>>>>>>
>>>>>>>> --
>>>>>>>> Lorenz Bühmann
>>>>>>>> AKSW group, University of Leipzig
>>>>>>>> Group: http://aksw.org - semantic web research center
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> --
>>>>>> Lorenz Bühmann
>>>>>> AKSW group, University of Leipzig
>>>>>> Group: http://aksw.org - semantic web research center
>>>>>>
>>>>>
>>>>
>>>
>>
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Just to report that the previous code is not correct.
I tried on
String qString6 = "prefix rdfs:<http://www.w3.org/2000/01/rdf-schema#> "
+ "prefix ex:<http://www.semanticweb.org/dataset1/> "
+ "prefix rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
+ " SELECT DISTINCT ?ind ?boss ?g where "
+ "{ "
+ " {?ind rdf:type ?z. } "
+ "UNION "
+ " {"
+ " { ?boss ex:isBossOf1 ?ind .}"
+ " UNION {?boss ex:isBossOf ?ind ."
+ " Filter(?boss=\"mathieu\") }"
+ "}"
+ "}";
and triple= + " { ?boss ex:isBossOf1 ?ind .}”
It produced:
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ { # Empty BGP
}
UNION
{ ?boss ex:isBossOf ?ind }
}
}
which eliminates the Filter too when it should not.
I am working on it.
Many Thanks,
Best Regards,
Carlo
> On 1 Feb 2016, at 22:55, Martynas Jusevičius <ma...@graphity.org> wrote:
>
> This thread got me thinking -- couldn't we have reusable,
> dereferenceable SPARQL optimizations/rewrites as SPARQL CONSTRUCTs
> over SPIN RDF? Which would be mappings between the original syntax
> tree and the optimized syntax tree.
>
> On Mon, Feb 1, 2016 at 8:55 PM, Carlo.Allocca <ca...@open.ac.uk> wrote:
>> Dear Andy, Lorenz and All,
>>
>> Thank you very much for your help and support.
>> I would like to share the first achievement based on your suggestions.
>>
>> I have implemented
>>
>> 1) public Element transform(ElementPathBlock eltPB)
>> 2) public Element transform(ElementGroup arg0, List<Element> arg1)
>>
>> running it over a number of example queries I obtain the expected results.
>> For example, for the input query
>>
>> String qString6 = "prefix rdfs:<http://www.w3.org/2000/01/rdf-schema#> "
>> + "prefix ex:<http://www.semanticweb.org/dataset1/> "
>> + "prefix rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
>> + " SELECT DISTINCT ?ind ?boss ?g where "
>> + "{ "
>> + " {?ind rdf:type ?z. } "
>> + "UNION "
>> + " {"
>> + " { ?boss ex:isBossOf1 ?ind .}"
>> + " UNION {?boss ex:isBossOf ?ind ."
>> + " Filter(?boss=\"mathieu\") }"
>> + "}"
>> + "}";
>>
>> when removing the triple (?boss ex:isBossOf ?ind .”), I get
>>
>> SELECT DISTINCT ?ind ?boss ?g
>> WHERE
>> { { ?ind rdf:type ?z }
>> UNION
>> { { ?boss ex:isBossOf1 ?ind }
>> UNION
>> { # Empty BGP
>>
>> }
>> }
>> }
>>
>> which is OK.
>> I just need to find out how to remove an ElementGroup which contains only one element which is the EMPTY one.
>> Of course, I need to do the same for the other case, e.g. OPTION, SUBquery, etc.
>>
>> Many Thanks for your help one again.
>> Best Regards,
>> Carlo
>>
>>
>>
>> == Here the code
>>
>>
>> @Override
>> public Element transform(ElementPathBlock eltPB) {
>> if (eltPB.isEmpty()) {
>> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] ElementPathBlock IS EMPTY:: " + eltPB.toString());
>> return eltPB;
>> }
>> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] ElementPathBlock:: " + eltPB.toString());
>> Iterator<TriplePath> l = eltPB.patternElts();
>> while (l.hasNext()) {
>> TriplePath tp = l.next();
>> if (tp.asTriple().matches(this.triple)) {
>> l.remove();
>> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] ElementPathBlock:: " + tp.toString()+" TRIPLE JUST REMOVED!!!");
>> //System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] TRIPLE JUST REMOVED!!! ");
>> System.out.println("");
>> return this.transform(eltPB);//eltPB;
>> }
>> }
>> return eltPB;
>> }
>>
>>
>> @Override
>> public Element transform(ElementGroup arg0, List<Element> arg1) {
>> //ElementGroup arg0New = new ElementGroup();
>>
>> List<Element> elemList = arg0.getElements();
>> Iterator<Element> itr = elemList.iterator();
>> while (itr.hasNext()) {
>> Element elem = itr.next();
>> if (elem instanceof ElementGroup) {
>> // if(((ElementGroup) elem).isEmpty()){
>> System.out.println("[RemoveOpTransform::visit(ElementGroup arg0)] ElementGroup IS EMPTY!!! " +((ElementGroup) elem).toString());
>> System.out.println("[RemoveOpTransform::visit(ElementGroup arg0)] List<Element> arg1 IS EMPTY!!! " +arg1.toString());
>> // }
>> }
>>
>> if (elem instanceof ElementFilter) {
>> //... check if this filter is the one that we should remove
>> //...get the variables of the triple pattern that we want to delete
>> Set<Var> tpVars = new HashSet();
>> Node subj = this.triple.getSubject();
>> if (subj.isVariable()) {
>> tpVars.add((Var) subj);
>> }
>> Node pred = this.triple.getPredicate();
>> if (pred.isVariable()) {
>> tpVars.add((Var) pred);
>> }
>> Node obj = this.triple.getObject();
>> if (obj.isVariable()) {
>> tpVars.add((Var) obj);
>> }
>> //...get the variables of the FILTER expression
>> Set<Var> expVars = ((ElementFilter) elem).getExpr().getVarsMentioned();
>> //...check whether the FILTER expression contains any of the triple pattern variable
>> for (Var var : expVars) {
>> //..if it does then we have to delete the entire FILTER expression
>> if (tpVars.contains(var)) {
>> System.out.println("[RemoveOpTransform::visit(ElementGroup arg0)] THE "+((ElementFilter) elem).toString() +"IS GOING TO BE REMOVED!!!");
>> //Expr e = new NodeValueBoolean(true);
>> //ElementFilter newFilter = new ElementFilter(e);
>> itr.remove();
>> return this.transform(arg0, arg1);
>> }
>> }
>>
>> }
>> }
>> // System.out.println("[RemoveOpTransform::transform(ElementGroup arg0)] arg1 " + arg1.toString());
>> // System.out.println("");
>> //return arg0New;
>> return arg0;
>> }
>>
>>
>>
>>
>>> On 31 Jan 2016, at 15:40, Carlo.Allocca <ca...@open.ac.uk> wrote:
>>>
>>> Dear Andy,
>>>
>>>
>>>> On 31 Jan 2016, at 15:25, Andy Seaborne <an...@apache.org> wrote:
>>>>
>>>> Cleaning up is slightly easier in the syntax because BGPs and filters are inside a group (nothing to do with GROUP - a syntax group is things between {}.
>>>>
>>>> So when you want to delete something, have some custom Element class 'ElementDeleteMe' to return from the ElementFilter or ElementPathBlock. Something that can not appear in a legal query. it does not need to implement anything.
>>>>
>>>> Then in
>>>> transform(ElementGroup el, List<Element> members) ;
>>>>
>>>> rewrite 'members' to remove any ElementDeleteMe.
>>>>
>>>> if members.size == 0
>>>> return ElementDeleteMe
>>>>
>>>> so it recursive works.
>>>>
>>>> Take care at the top of syntax tree.
>>>>
>>> Thank you for the details.
>>> It seems that I should be using org.apache.jena.sparql.syntax rather than org.apache.jena.sparql.algebra.
>>> I will try to implement it as suggested above.
>>>
>>> Many Thanks,
>>> Best Regards,
>>> Carlo
>>>
>>>
>>>> Andy
>>>>
>>>> On 31/01/16 15:11, Carlo.Allocca wrote:
>>>>> Hello Lorenz,
>>>>>
>>>>>
>>>>> Sure no problem.
>>>>> I can share it here. In case you have suggest any other place I will do so.
>>>>>
>>>>> Please, let me know.
>>>>> Many Thanks,
>>>>>
>>>>> Best Regards,
>>>>> Carlo
>>>>>
>>>>>> On 31 Jan 2016, at 15:07, Lorenz Bühmann <bu...@informatik.uni-leipzig.de> wrote:
>>>>>>
>>>>>> Hello Carlo,
>>>>>>
>>>>>> I'm sure you'll make it, but maybe you should also share the complete code somehow? Maybe this makes it easier for people to help you.
>>>>>>
>>>>>> Lorenz
>>>>>>
>>>>>>> Hello Lorenz,
>>>>>>>
>>>>>>> Thank you very much for your help.
>>>>>>> Some comments follow in line.
>>>>>>>
>>>>>>>
>>>>>>>> On 31 Jan 2016, at 13:36, Lorenz Bühmann <bu...@informatik.uni-leipzig.de> wrote:
>>>>>>>>
>>>>>>>> Hello Carlo,
>>>>>>>>
>>>>>>>> there is usually no link from a child node to its parent in the JENA data structures.
>>>>>>> It is very good to confirm it as I don’t spend more time to look for it. I thought that I was missing some JENA data structure and packages.
>>>>>>>
>>>>>>>> That means you have to keep track of it when you're processing the parents. Why not run some "clean up" after each child has been processed? E.g. check if there is no BGP left and thus mark this current parent as also "toBeRemoved”.
>>>>>>> Sure. I have already started doing it by using some boolean variables. Let’s see if I can make it.
>>>>>>> Otherwise I have to develop a module that transform the Jena Query Expression into a Tree based representation and then apply the triple remove operation.
>>>>>>>
>>>>>>> Thank you again for your support and answers.
>>>>>>>
>>>>>>> Best Regards,
>>>>>>> Carlo
>>>>>>>
>>>>>>>> Lorenz
>>>>>>>>
>>>>>>>>> and of course, the below is for processing an BGP:
>>>>>>>>>
>>>>>>>>> @Override
>>>>>>>>> public Op transform(OpBGP opBGP) {
>>>>>>>>>
>>>>>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter " + opBGPCounter++);
>>>>>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] " + opBGP.toString());
>>>>>>>>> System.out.println("");
>>>>>>>>> Op newOpBGP = opBGP.copy();
>>>>>>>>> BasicPattern newBP = ((OpBGP) newOpBGP).getPattern();
>>>>>>>>> List<Triple> tripleList = newBP.getList();
>>>>>>>>>
>>>>>>>>> Iterator<Triple> itr = tripleList.iterator();
>>>>>>>>> while (itr.hasNext()) {
>>>>>>>>> Triple tp = itr.next();
>>>>>>>>> if (tp.matches(this.triple)) {
>>>>>>>>> itr.remove();
>>>>>>>>> isParent = true;
>>>>>>>>> isStarted = true;
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>> //...it can be empty
>>>>>>>>> if (((OpBGP) newOpBGP).getPattern().getList().isEmpty()) {
>>>>>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty " + opBGP.toString());
>>>>>>>>> //return subOp;
>>>>>>>>> }
>>>>>>>>> return newOpBGP;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Many Thanks,
>>>>>>>>> Carlo.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>> On 31 Jan 2016, at 04:36, Carlo.Allocca <ca...@open.ac.uk> wrote:
>>>>>>>>>>
>>>>>>>>>> Dear Andy,
>>>>>>>>>>
>>>>>>>>>> Thank you very much one more time.
>>>>>>>>>>
>>>>>>>>>> Please, some comments follow in line.
>>>>>>>>>>
>>>>>>>>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>>>>>>>>
>>>>>>>>>> On 30/01/16 15:52, Carlo.Allocca wrote:
>>>>>>>>>> Hello Lorenz,
>>>>>>>>>>
>>>>>>>>>> Thank you for your help.
>>>>>>>>>>
>>>>>>>>>> It was clear to me that I have to remove from the parent expression and such is that using a patter-based approach
>>>>>>>>>> make it a bit difficult. I tried three of them and I got to the same results.
>>>>>>>>>>
>>>>>>>>>> You need to process the parent, not just the ElementFilter.
>>>>>>>>>>
>>>>>>>>>> How can I process the parent?
>>>>>>>>>> My understanding is:
>>>>>>>>>>
>>>>>>>>>> 1. Building the Abstract Query Tree: Op op = Algebra.compile(q);
>>>>>>>>>>
>>>>>>>>>> For example, given the query
>>>>>>>>>>
>>>>>>>>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>>>>>>>>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>>>>>>>>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>>>>>>>>>
>>>>>>>>>> SELECT DISTINCT ?ind ?boss ?g
>>>>>>>>>> WHERE
>>>>>>>>>> { { ?ind rdf:type ?z }
>>>>>>>>>> UNION
>>>>>>>>>> { ?boss ex:isBossOf ?ind
>>>>>>>>>> FILTER ( ?boss = "mathieu" )
>>>>>>>>>> }
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> I obtain
>>>>>>>>>>
>>>>>>>>>> (distinct
>>>>>>>>>> (project (?ind ?boss ?g)
>>>>>>>>>> (union
>>>>>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>>>> (filter (= ?boss "mathieu")
>>>>>>>>>> (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))))))
>>>>>>>>>>
>>>>>>>>>> 2) Travere the tree to modify its internal structure. In terms of code, I can write:
>>>>>>>>>>
>>>>>>>>>> (A) Transform transform = new TransformRemoveOp(q,tp) ;
>>>>>>>>>> (B) op = Transformer.transform(transform, op);
>>>>>>>>>>
>>>>>>>>>> where TransformRemoveOp implements Transform interface.
>>>>>>>>>> It seems that there is no link between children and parent that can be used to figure out at which level the process is and modify the Tree structure, accordingly. Please correct me if I am wrong.
>>>>>>>>>> In fact running it over the above example, I got the following:
>>>>>>>>>>
>>>>>>>>>> =========== DURING
>>>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 1
>>>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 2
>>>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty (bgp
>>>>>>>>>> )
>>>>>>>>>>
>>>>>>>>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter (filter (= ?boss "mathieu")
>>>>>>>>>> (bgp
>>>>>>>>>> ))
>>>>>>>>>>
>>>>>>>>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name bgp
>>>>>>>>>>
>>>>>>>>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] left: (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>>>>
>>>>>>>>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] right: (filter (exprlist (= ?boss "mathieu") true)
>>>>>>>>>> (bgp
>>>>>>>>>> ))
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> [TransformRemoveOp::transform(OpProject opProject, Op subOp)] (project (?ind ?boss ?g)
>>>>>>>>>> (union
>>>>>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>>>> (filter (exprlist (= ?boss "mathieu") true)
>>>>>>>>>> (bgp
>>>>>>>>>> ))))
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> [TransformRemoveOp::transform(OpDistinct opDistinct, Op subOp)] (distinct
>>>>>>>>>> (project (?ind ?boss ?g)
>>>>>>>>>> (union
>>>>>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>>>> (filter (exprlist (= ?boss "mathieu") true)
>>>>>>>>>> (bgp
>>>>>>>>>> )))))
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Moreover, implementing a first version of the OpFilter as reported below:
>>>>>>>>>>
>>>>>>>>>> @Override
>>>>>>>>>> public Op transform(OpFilter opFilter, Op subOp) {
>>>>>>>>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter " + opFilter.toString());
>>>>>>>>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name " + subOp.getName());
>>>>>>>>>> System.out.println("");
>>>>>>>>>>
>>>>>>>>>> if (isParent == false) {
>>>>>>>>>> return opFilter;
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> //...get the variables of the triple pattern that we want to delete
>>>>>>>>>> Set<Var> tpVars = new HashSet();
>>>>>>>>>> Node subj = this.triple.getSubject();
>>>>>>>>>> if (subj.isVariable()) {
>>>>>>>>>> tpVars.add((Var) subj);
>>>>>>>>>> }
>>>>>>>>>> Node pred = this.triple.getPredicate();
>>>>>>>>>> if (pred.isVariable()) {
>>>>>>>>>> tpVars.add((Var) pred);
>>>>>>>>>> }
>>>>>>>>>> Node obj = this.triple.getObject();
>>>>>>>>>> if (obj.isVariable()) {
>>>>>>>>>> tpVars.add((Var) obj);
>>>>>>>>>> }
>>>>>>>>>> //...get the variables of the FILTER expression
>>>>>>>>>> Op opNew = opFilter.copy(subOp);
>>>>>>>>>> Set<Var> expVars = ((OpFilter) opNew).getExprs().getVarsMentioned();
>>>>>>>>>>
>>>>>>>>>> //...check whether the FILTER expression contains any of the triple pattern variable
>>>>>>>>>> boolean isContained = false;
>>>>>>>>>> for (Var var : expVars) {
>>>>>>>>>> //..if it does then we have to delete the entire FILTER expression
>>>>>>>>>> if (tpVars.contains(var)) {
>>>>>>>>>> isContained = true;
>>>>>>>>>> break;
>>>>>>>>>> }
>>>>>>>>>> }
>>>>>>>>>> //... if the filter contains any variable of the triple that has been removed, then....
>>>>>>>>>> if (isContained) {
>>>>>>>>>> Op newOP;
>>>>>>>>>> Expr e;
>>>>>>>>>> if (subOp instanceof OpBGP) {
>>>>>>>>>> if (((OpBGP) subOp).getPattern().getList().isEmpty()) {
>>>>>>>>>> e = new NodeValueBoolean(true);
>>>>>>>>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>>>>>>>>> return newOP;
>>>>>>>>>> } else {
>>>>>>>>>> e = new NodeValueBoolean(false);
>>>>>>>>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>>>>>>>>> return newOP;
>>>>>>>>>> }
>>>>>>>>>> }
>>>>>>>>>> }
>>>>>>>>>> return opFilter;
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> It produces the following SPARQL query:
>>>>>>>>>>
>>>>>>>>>> SELECT DISTINCT ?ind ?boss ?g
>>>>>>>>>> WHERE
>>>>>>>>>> { { ?ind a ?z }
>>>>>>>>>> UNION
>>>>>>>>>> { # Empty BGP
>>>>>>>>>>
>>>>>>>>>> FILTER ( ?boss = "mathieu" )
>>>>>>>>>> FILTER ( true )
>>>>>>>>>> }
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> It seems quite challenging even transform the expression of "?boss = “mathieu” into “true” (as reported above) does not work as It should.
>>>>>>>>>>
>>>>>>>>>> If anyone could help me who is more experienced with this kind of task, I would be very very grateful.
>>>>>>>>>> I would like to see something concrete in sense of line of code as I am using.
>>>>>>>>>>
>>>>>>>>>> Many Thanks,
>>>>>>>>>> Best Regards,
>>>>>>>>>> Carlo
>>>>>>>>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>>>>>>>>
>>>>>>>>>> element has active parts
>>>>>>>>>>
>>>>>>>>>> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>>>>>>>>>
>>>>>>>> --
>>>>>>>> Lorenz Bühmann
>>>>>>>> AKSW group, University of Leipzig
>>>>>>>> Group: http://aksw.org - semantic web research center
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> --
>>>>>> Lorenz Bühmann
>>>>>> AKSW group, University of Leipzig
>>>>>> Group: http://aksw.org - semantic web research center
>>>>>>
>>>>>
>>>>
>>>
>>
Re: How to remove consistently a triple pattern given a SPARQL query?
Posted by Martynas Jusevičius <ma...@graphity.org>.
This thread got me thinking -- couldn't we have reusable,
dereferenceable SPARQL optimizations/rewrites as SPARQL CONSTRUCTs
over SPIN RDF? Which would be mappings between the original syntax
tree and the optimized syntax tree.
On Mon, Feb 1, 2016 at 8:55 PM, Carlo.Allocca <ca...@open.ac.uk> wrote:
> Dear Andy, Lorenz and All,
>
> Thank you very much for your help and support.
> I would like to share the first achievement based on your suggestions.
>
> I have implemented
>
> 1) public Element transform(ElementPathBlock eltPB)
> 2) public Element transform(ElementGroup arg0, List<Element> arg1)
>
> running it over a number of example queries I obtain the expected results.
> For example, for the input query
>
> String qString6 = "prefix rdfs:<http://www.w3.org/2000/01/rdf-schema#> "
> + "prefix ex:<http://www.semanticweb.org/dataset1/> "
> + "prefix rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
> + " SELECT DISTINCT ?ind ?boss ?g where "
> + "{ "
> + " {?ind rdf:type ?z. } "
> + "UNION "
> + " {"
> + " { ?boss ex:isBossOf1 ?ind .}"
> + " UNION {?boss ex:isBossOf ?ind ."
> + " Filter(?boss=\"mathieu\") }"
> + "}"
> + "}";
>
> when removing the triple (?boss ex:isBossOf ?ind .”), I get
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { # Empty BGP
>
> }
> }
> }
>
> which is OK.
> I just need to find out how to remove an ElementGroup which contains only one element which is the EMPTY one.
> Of course, I need to do the same for the other case, e.g. OPTION, SUBquery, etc.
>
> Many Thanks for your help one again.
> Best Regards,
> Carlo
>
>
>
> == Here the code
>
>
> @Override
> public Element transform(ElementPathBlock eltPB) {
> if (eltPB.isEmpty()) {
> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] ElementPathBlock IS EMPTY:: " + eltPB.toString());
> return eltPB;
> }
> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] ElementPathBlock:: " + eltPB.toString());
> Iterator<TriplePath> l = eltPB.patternElts();
> while (l.hasNext()) {
> TriplePath tp = l.next();
> if (tp.asTriple().matches(this.triple)) {
> l.remove();
> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] ElementPathBlock:: " + tp.toString()+" TRIPLE JUST REMOVED!!!");
> //System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] TRIPLE JUST REMOVED!!! ");
> System.out.println("");
> return this.transform(eltPB);//eltPB;
> }
> }
> return eltPB;
> }
>
>
> @Override
> public Element transform(ElementGroup arg0, List<Element> arg1) {
> //ElementGroup arg0New = new ElementGroup();
>
> List<Element> elemList = arg0.getElements();
> Iterator<Element> itr = elemList.iterator();
> while (itr.hasNext()) {
> Element elem = itr.next();
> if (elem instanceof ElementGroup) {
> // if(((ElementGroup) elem).isEmpty()){
> System.out.println("[RemoveOpTransform::visit(ElementGroup arg0)] ElementGroup IS EMPTY!!! " +((ElementGroup) elem).toString());
> System.out.println("[RemoveOpTransform::visit(ElementGroup arg0)] List<Element> arg1 IS EMPTY!!! " +arg1.toString());
> // }
> }
>
> if (elem instanceof ElementFilter) {
> //... check if this filter is the one that we should remove
> //...get the variables of the triple pattern that we want to delete
> Set<Var> tpVars = new HashSet();
> Node subj = this.triple.getSubject();
> if (subj.isVariable()) {
> tpVars.add((Var) subj);
> }
> Node pred = this.triple.getPredicate();
> if (pred.isVariable()) {
> tpVars.add((Var) pred);
> }
> Node obj = this.triple.getObject();
> if (obj.isVariable()) {
> tpVars.add((Var) obj);
> }
> //...get the variables of the FILTER expression
> Set<Var> expVars = ((ElementFilter) elem).getExpr().getVarsMentioned();
> //...check whether the FILTER expression contains any of the triple pattern variable
> for (Var var : expVars) {
> //..if it does then we have to delete the entire FILTER expression
> if (tpVars.contains(var)) {
> System.out.println("[RemoveOpTransform::visit(ElementGroup arg0)] THE "+((ElementFilter) elem).toString() +"IS GOING TO BE REMOVED!!!");
> //Expr e = new NodeValueBoolean(true);
> //ElementFilter newFilter = new ElementFilter(e);
> itr.remove();
> return this.transform(arg0, arg1);
> }
> }
>
> }
> }
> // System.out.println("[RemoveOpTransform::transform(ElementGroup arg0)] arg1 " + arg1.toString());
> // System.out.println("");
> //return arg0New;
> return arg0;
> }
>
>
>
>
>> On 31 Jan 2016, at 15:40, Carlo.Allocca <ca...@open.ac.uk> wrote:
>>
>> Dear Andy,
>>
>>
>>> On 31 Jan 2016, at 15:25, Andy Seaborne <an...@apache.org> wrote:
>>>
>>> Cleaning up is slightly easier in the syntax because BGPs and filters are inside a group (nothing to do with GROUP - a syntax group is things between {}.
>>>
>>> So when you want to delete something, have some custom Element class 'ElementDeleteMe' to return from the ElementFilter or ElementPathBlock. Something that can not appear in a legal query. it does not need to implement anything.
>>>
>>> Then in
>>> transform(ElementGroup el, List<Element> members) ;
>>>
>>> rewrite 'members' to remove any ElementDeleteMe.
>>>
>>> if members.size == 0
>>> return ElementDeleteMe
>>>
>>> so it recursive works.
>>>
>>> Take care at the top of syntax tree.
>>>
>> Thank you for the details.
>> It seems that I should be using org.apache.jena.sparql.syntax rather than org.apache.jena.sparql.algebra.
>> I will try to implement it as suggested above.
>>
>> Many Thanks,
>> Best Regards,
>> Carlo
>>
>>
>>> Andy
>>>
>>> On 31/01/16 15:11, Carlo.Allocca wrote:
>>>> Hello Lorenz,
>>>>
>>>>
>>>> Sure no problem.
>>>> I can share it here. In case you have suggest any other place I will do so.
>>>>
>>>> Please, let me know.
>>>> Many Thanks,
>>>>
>>>> Best Regards,
>>>> Carlo
>>>>
>>>>> On 31 Jan 2016, at 15:07, Lorenz Bühmann <bu...@informatik.uni-leipzig.de> wrote:
>>>>>
>>>>> Hello Carlo,
>>>>>
>>>>> I'm sure you'll make it, but maybe you should also share the complete code somehow? Maybe this makes it easier for people to help you.
>>>>>
>>>>> Lorenz
>>>>>
>>>>>> Hello Lorenz,
>>>>>>
>>>>>> Thank you very much for your help.
>>>>>> Some comments follow in line.
>>>>>>
>>>>>>
>>>>>>> On 31 Jan 2016, at 13:36, Lorenz Bühmann <bu...@informatik.uni-leipzig.de> wrote:
>>>>>>>
>>>>>>> Hello Carlo,
>>>>>>>
>>>>>>> there is usually no link from a child node to its parent in the JENA data structures.
>>>>>> It is very good to confirm it as I don’t spend more time to look for it. I thought that I was missing some JENA data structure and packages.
>>>>>>
>>>>>>> That means you have to keep track of it when you're processing the parents. Why not run some "clean up" after each child has been processed? E.g. check if there is no BGP left and thus mark this current parent as also "toBeRemoved”.
>>>>>> Sure. I have already started doing it by using some boolean variables. Let’s see if I can make it.
>>>>>> Otherwise I have to develop a module that transform the Jena Query Expression into a Tree based representation and then apply the triple remove operation.
>>>>>>
>>>>>> Thank you again for your support and answers.
>>>>>>
>>>>>> Best Regards,
>>>>>> Carlo
>>>>>>
>>>>>>> Lorenz
>>>>>>>
>>>>>>>> and of course, the below is for processing an BGP:
>>>>>>>>
>>>>>>>> @Override
>>>>>>>> public Op transform(OpBGP opBGP) {
>>>>>>>>
>>>>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter " + opBGPCounter++);
>>>>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] " + opBGP.toString());
>>>>>>>> System.out.println("");
>>>>>>>> Op newOpBGP = opBGP.copy();
>>>>>>>> BasicPattern newBP = ((OpBGP) newOpBGP).getPattern();
>>>>>>>> List<Triple> tripleList = newBP.getList();
>>>>>>>>
>>>>>>>> Iterator<Triple> itr = tripleList.iterator();
>>>>>>>> while (itr.hasNext()) {
>>>>>>>> Triple tp = itr.next();
>>>>>>>> if (tp.matches(this.triple)) {
>>>>>>>> itr.remove();
>>>>>>>> isParent = true;
>>>>>>>> isStarted = true;
>>>>>>>> }
>>>>>>>> }
>>>>>>>> //...it can be empty
>>>>>>>> if (((OpBGP) newOpBGP).getPattern().getList().isEmpty()) {
>>>>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty " + opBGP.toString());
>>>>>>>> //return subOp;
>>>>>>>> }
>>>>>>>> return newOpBGP;
>>>>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>> Many Thanks,
>>>>>>>> Carlo.
>>>>>>>>
>>>>>>>>
>>>>>>>>> On 31 Jan 2016, at 04:36, Carlo.Allocca <ca...@open.ac.uk> wrote:
>>>>>>>>>
>>>>>>>>> Dear Andy,
>>>>>>>>>
>>>>>>>>> Thank you very much one more time.
>>>>>>>>>
>>>>>>>>> Please, some comments follow in line.
>>>>>>>>>
>>>>>>>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>>>>>>>
>>>>>>>>> On 30/01/16 15:52, Carlo.Allocca wrote:
>>>>>>>>> Hello Lorenz,
>>>>>>>>>
>>>>>>>>> Thank you for your help.
>>>>>>>>>
>>>>>>>>> It was clear to me that I have to remove from the parent expression and such is that using a patter-based approach
>>>>>>>>> make it a bit difficult. I tried three of them and I got to the same results.
>>>>>>>>>
>>>>>>>>> You need to process the parent, not just the ElementFilter.
>>>>>>>>>
>>>>>>>>> How can I process the parent?
>>>>>>>>> My understanding is:
>>>>>>>>>
>>>>>>>>> 1. Building the Abstract Query Tree: Op op = Algebra.compile(q);
>>>>>>>>>
>>>>>>>>> For example, given the query
>>>>>>>>>
>>>>>>>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>>>>>>>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>>>>>>>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>>>>>>>>
>>>>>>>>> SELECT DISTINCT ?ind ?boss ?g
>>>>>>>>> WHERE
>>>>>>>>> { { ?ind rdf:type ?z }
>>>>>>>>> UNION
>>>>>>>>> { ?boss ex:isBossOf ?ind
>>>>>>>>> FILTER ( ?boss = "mathieu" )
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> I obtain
>>>>>>>>>
>>>>>>>>> (distinct
>>>>>>>>> (project (?ind ?boss ?g)
>>>>>>>>> (union
>>>>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>>> (filter (= ?boss "mathieu")
>>>>>>>>> (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))))))
>>>>>>>>>
>>>>>>>>> 2) Travere the tree to modify its internal structure. In terms of code, I can write:
>>>>>>>>>
>>>>>>>>> (A) Transform transform = new TransformRemoveOp(q,tp) ;
>>>>>>>>> (B) op = Transformer.transform(transform, op);
>>>>>>>>>
>>>>>>>>> where TransformRemoveOp implements Transform interface.
>>>>>>>>> It seems that there is no link between children and parent that can be used to figure out at which level the process is and modify the Tree structure, accordingly. Please correct me if I am wrong.
>>>>>>>>> In fact running it over the above example, I got the following:
>>>>>>>>>
>>>>>>>>> =========== DURING
>>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 1
>>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 2
>>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty (bgp
>>>>>>>>> )
>>>>>>>>>
>>>>>>>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter (filter (= ?boss "mathieu")
>>>>>>>>> (bgp
>>>>>>>>> ))
>>>>>>>>>
>>>>>>>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name bgp
>>>>>>>>>
>>>>>>>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] left: (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>>>
>>>>>>>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] right: (filter (exprlist (= ?boss "mathieu") true)
>>>>>>>>> (bgp
>>>>>>>>> ))
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> [TransformRemoveOp::transform(OpProject opProject, Op subOp)] (project (?ind ?boss ?g)
>>>>>>>>> (union
>>>>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>>> (filter (exprlist (= ?boss "mathieu") true)
>>>>>>>>> (bgp
>>>>>>>>> ))))
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> [TransformRemoveOp::transform(OpDistinct opDistinct, Op subOp)] (distinct
>>>>>>>>> (project (?ind ?boss ?g)
>>>>>>>>> (union
>>>>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>>> (filter (exprlist (= ?boss "mathieu") true)
>>>>>>>>> (bgp
>>>>>>>>> )))))
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Moreover, implementing a first version of the OpFilter as reported below:
>>>>>>>>>
>>>>>>>>> @Override
>>>>>>>>> public Op transform(OpFilter opFilter, Op subOp) {
>>>>>>>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter " + opFilter.toString());
>>>>>>>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name " + subOp.getName());
>>>>>>>>> System.out.println("");
>>>>>>>>>
>>>>>>>>> if (isParent == false) {
>>>>>>>>> return opFilter;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> //...get the variables of the triple pattern that we want to delete
>>>>>>>>> Set<Var> tpVars = new HashSet();
>>>>>>>>> Node subj = this.triple.getSubject();
>>>>>>>>> if (subj.isVariable()) {
>>>>>>>>> tpVars.add((Var) subj);
>>>>>>>>> }
>>>>>>>>> Node pred = this.triple.getPredicate();
>>>>>>>>> if (pred.isVariable()) {
>>>>>>>>> tpVars.add((Var) pred);
>>>>>>>>> }
>>>>>>>>> Node obj = this.triple.getObject();
>>>>>>>>> if (obj.isVariable()) {
>>>>>>>>> tpVars.add((Var) obj);
>>>>>>>>> }
>>>>>>>>> //...get the variables of the FILTER expression
>>>>>>>>> Op opNew = opFilter.copy(subOp);
>>>>>>>>> Set<Var> expVars = ((OpFilter) opNew).getExprs().getVarsMentioned();
>>>>>>>>>
>>>>>>>>> //...check whether the FILTER expression contains any of the triple pattern variable
>>>>>>>>> boolean isContained = false;
>>>>>>>>> for (Var var : expVars) {
>>>>>>>>> //..if it does then we have to delete the entire FILTER expression
>>>>>>>>> if (tpVars.contains(var)) {
>>>>>>>>> isContained = true;
>>>>>>>>> break;
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>> //... if the filter contains any variable of the triple that has been removed, then....
>>>>>>>>> if (isContained) {
>>>>>>>>> Op newOP;
>>>>>>>>> Expr e;
>>>>>>>>> if (subOp instanceof OpBGP) {
>>>>>>>>> if (((OpBGP) subOp).getPattern().getList().isEmpty()) {
>>>>>>>>> e = new NodeValueBoolean(true);
>>>>>>>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>>>>>>>> return newOP;
>>>>>>>>> } else {
>>>>>>>>> e = new NodeValueBoolean(false);
>>>>>>>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>>>>>>>> return newOP;
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>> return opFilter;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> It produces the following SPARQL query:
>>>>>>>>>
>>>>>>>>> SELECT DISTINCT ?ind ?boss ?g
>>>>>>>>> WHERE
>>>>>>>>> { { ?ind a ?z }
>>>>>>>>> UNION
>>>>>>>>> { # Empty BGP
>>>>>>>>>
>>>>>>>>> FILTER ( ?boss = "mathieu" )
>>>>>>>>> FILTER ( true )
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> It seems quite challenging even transform the expression of "?boss = “mathieu” into “true” (as reported above) does not work as It should.
>>>>>>>>>
>>>>>>>>> If anyone could help me who is more experienced with this kind of task, I would be very very grateful.
>>>>>>>>> I would like to see something concrete in sense of line of code as I am using.
>>>>>>>>>
>>>>>>>>> Many Thanks,
>>>>>>>>> Best Regards,
>>>>>>>>> Carlo
>>>>>>>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>>>>>>>
>>>>>>>>> element has active parts
>>>>>>>>>
>>>>>>>>> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>>>>>>>>
>>>>>>> --
>>>>>>> Lorenz Bühmann
>>>>>>> AKSW group, University of Leipzig
>>>>>>> Group: http://aksw.org - semantic web research center
>>>>>>>
>>>>>>
>>>>>>
>>>>> --
>>>>> Lorenz Bühmann
>>>>> AKSW group, University of Leipzig
>>>>> Group: http://aksw.org - semantic web research center
>>>>>
>>>>
>>>
>>
>
Re: How to remove consistently a triple pattern given a SPARQL query?
Posted by Andy Seaborne <an...@apache.org>.
> when removing the triple (?boss ex:isBossOf ?ind .”), I get
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { { ?boss ex:isBossOf1 ?ind }
> UNION
> { # Empty BGP
>
> }
> }
> }
>
> which is OK.
> I just need to find out how to remove an ElementGroup which contains only one element which is the EMPTY one.
> Of course, I need to do the same for the other case, e.g. OPTION, SUBquery, etc.
Do note that evaluating {} (empty syntax group) yields one row of zero
columns - it contributes to the overall results (it's the join identity).
Now you have to look at all the elements that have a group in
ElementUnion, ElementOptional, ElementMinus, ...
That is what ElementTransformCleanGroupsOfOne does, except it looks for
"groups of one"
.. UNION { { stuff } }
and isn't to fussy about finding them all (it's an optimization, more a
tidying of the tree, not a change in the effect of a query which is what
removing triple patterns is).
And of course changes from the bottom could potentially cause change all
the way up to the top of the syntax tree.
also: they maybe be original, legal empty groups in the tree.
Andy
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Dear Andy, Lorenz and All,
Thank you very much for your help and support.
I would like to share the first achievement based on your suggestions.
I have implemented
1) public Element transform(ElementPathBlock eltPB)
2) public Element transform(ElementGroup arg0, List<Element> arg1)
running it over a number of example queries I obtain the expected results.
For example, for the input query
String qString6 = "prefix rdfs:<http://www.w3.org/2000/01/rdf-schema#> "
+ "prefix ex:<http://www.semanticweb.org/dataset1/> "
+ "prefix rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
+ " SELECT DISTINCT ?ind ?boss ?g where "
+ "{ "
+ " {?ind rdf:type ?z. } "
+ "UNION "
+ " {"
+ " { ?boss ex:isBossOf1 ?ind .}"
+ " UNION {?boss ex:isBossOf ?ind ."
+ " Filter(?boss=\"mathieu\") }"
+ "}"
+ "}";
when removing the triple (?boss ex:isBossOf ?ind .”), I get
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ { ?boss ex:isBossOf1 ?ind }
UNION
{ # Empty BGP
}
}
}
which is OK.
I just need to find out how to remove an ElementGroup which contains only one element which is the EMPTY one.
Of course, I need to do the same for the other case, e.g. OPTION, SUBquery, etc.
Many Thanks for your help one again.
Best Regards,
Carlo
== Here the code
@Override
public Element transform(ElementPathBlock eltPB) {
if (eltPB.isEmpty()) {
System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] ElementPathBlock IS EMPTY:: " + eltPB.toString());
return eltPB;
}
System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] ElementPathBlock:: " + eltPB.toString());
Iterator<TriplePath> l = eltPB.patternElts();
while (l.hasNext()) {
TriplePath tp = l.next();
if (tp.asTriple().matches(this.triple)) {
l.remove();
System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] ElementPathBlock:: " + tp.toString()+" TRIPLE JUST REMOVED!!!");
//System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] TRIPLE JUST REMOVED!!! ");
System.out.println("");
return this.transform(eltPB);//eltPB;
}
}
return eltPB;
}
@Override
public Element transform(ElementGroup arg0, List<Element> arg1) {
//ElementGroup arg0New = new ElementGroup();
List<Element> elemList = arg0.getElements();
Iterator<Element> itr = elemList.iterator();
while (itr.hasNext()) {
Element elem = itr.next();
if (elem instanceof ElementGroup) {
// if(((ElementGroup) elem).isEmpty()){
System.out.println("[RemoveOpTransform::visit(ElementGroup arg0)] ElementGroup IS EMPTY!!! " +((ElementGroup) elem).toString());
System.out.println("[RemoveOpTransform::visit(ElementGroup arg0)] List<Element> arg1 IS EMPTY!!! " +arg1.toString());
// }
}
if (elem instanceof ElementFilter) {
//... check if this filter is the one that we should remove
//...get the variables of the triple pattern that we want to delete
Set<Var> tpVars = new HashSet();
Node subj = this.triple.getSubject();
if (subj.isVariable()) {
tpVars.add((Var) subj);
}
Node pred = this.triple.getPredicate();
if (pred.isVariable()) {
tpVars.add((Var) pred);
}
Node obj = this.triple.getObject();
if (obj.isVariable()) {
tpVars.add((Var) obj);
}
//...get the variables of the FILTER expression
Set<Var> expVars = ((ElementFilter) elem).getExpr().getVarsMentioned();
//...check whether the FILTER expression contains any of the triple pattern variable
for (Var var : expVars) {
//..if it does then we have to delete the entire FILTER expression
if (tpVars.contains(var)) {
System.out.println("[RemoveOpTransform::visit(ElementGroup arg0)] THE "+((ElementFilter) elem).toString() +"IS GOING TO BE REMOVED!!!");
//Expr e = new NodeValueBoolean(true);
//ElementFilter newFilter = new ElementFilter(e);
itr.remove();
return this.transform(arg0, arg1);
}
}
}
}
// System.out.println("[RemoveOpTransform::transform(ElementGroup arg0)] arg1 " + arg1.toString());
// System.out.println("");
//return arg0New;
return arg0;
}
> On 31 Jan 2016, at 15:40, Carlo.Allocca <ca...@open.ac.uk> wrote:
>
> Dear Andy,
>
>
>> On 31 Jan 2016, at 15:25, Andy Seaborne <an...@apache.org> wrote:
>>
>> Cleaning up is slightly easier in the syntax because BGPs and filters are inside a group (nothing to do with GROUP - a syntax group is things between {}.
>>
>> So when you want to delete something, have some custom Element class 'ElementDeleteMe' to return from the ElementFilter or ElementPathBlock. Something that can not appear in a legal query. it does not need to implement anything.
>>
>> Then in
>> transform(ElementGroup el, List<Element> members) ;
>>
>> rewrite 'members' to remove any ElementDeleteMe.
>>
>> if members.size == 0
>> return ElementDeleteMe
>>
>> so it recursive works.
>>
>> Take care at the top of syntax tree.
>>
> Thank you for the details.
> It seems that I should be using org.apache.jena.sparql.syntax rather than org.apache.jena.sparql.algebra.
> I will try to implement it as suggested above.
>
> Many Thanks,
> Best Regards,
> Carlo
>
>
>> Andy
>>
>> On 31/01/16 15:11, Carlo.Allocca wrote:
>>> Hello Lorenz,
>>>
>>>
>>> Sure no problem.
>>> I can share it here. In case you have suggest any other place I will do so.
>>>
>>> Please, let me know.
>>> Many Thanks,
>>>
>>> Best Regards,
>>> Carlo
>>>
>>>> On 31 Jan 2016, at 15:07, Lorenz Bühmann <bu...@informatik.uni-leipzig.de> wrote:
>>>>
>>>> Hello Carlo,
>>>>
>>>> I'm sure you'll make it, but maybe you should also share the complete code somehow? Maybe this makes it easier for people to help you.
>>>>
>>>> Lorenz
>>>>
>>>>> Hello Lorenz,
>>>>>
>>>>> Thank you very much for your help.
>>>>> Some comments follow in line.
>>>>>
>>>>>
>>>>>> On 31 Jan 2016, at 13:36, Lorenz Bühmann <bu...@informatik.uni-leipzig.de> wrote:
>>>>>>
>>>>>> Hello Carlo,
>>>>>>
>>>>>> there is usually no link from a child node to its parent in the JENA data structures.
>>>>> It is very good to confirm it as I don’t spend more time to look for it. I thought that I was missing some JENA data structure and packages.
>>>>>
>>>>>> That means you have to keep track of it when you're processing the parents. Why not run some "clean up" after each child has been processed? E.g. check if there is no BGP left and thus mark this current parent as also "toBeRemoved”.
>>>>> Sure. I have already started doing it by using some boolean variables. Let’s see if I can make it.
>>>>> Otherwise I have to develop a module that transform the Jena Query Expression into a Tree based representation and then apply the triple remove operation.
>>>>>
>>>>> Thank you again for your support and answers.
>>>>>
>>>>> Best Regards,
>>>>> Carlo
>>>>>
>>>>>> Lorenz
>>>>>>
>>>>>>> and of course, the below is for processing an BGP:
>>>>>>>
>>>>>>> @Override
>>>>>>> public Op transform(OpBGP opBGP) {
>>>>>>>
>>>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter " + opBGPCounter++);
>>>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] " + opBGP.toString());
>>>>>>> System.out.println("");
>>>>>>> Op newOpBGP = opBGP.copy();
>>>>>>> BasicPattern newBP = ((OpBGP) newOpBGP).getPattern();
>>>>>>> List<Triple> tripleList = newBP.getList();
>>>>>>>
>>>>>>> Iterator<Triple> itr = tripleList.iterator();
>>>>>>> while (itr.hasNext()) {
>>>>>>> Triple tp = itr.next();
>>>>>>> if (tp.matches(this.triple)) {
>>>>>>> itr.remove();
>>>>>>> isParent = true;
>>>>>>> isStarted = true;
>>>>>>> }
>>>>>>> }
>>>>>>> //...it can be empty
>>>>>>> if (((OpBGP) newOpBGP).getPattern().getList().isEmpty()) {
>>>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty " + opBGP.toString());
>>>>>>> //return subOp;
>>>>>>> }
>>>>>>> return newOpBGP;
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>> Many Thanks,
>>>>>>> Carlo.
>>>>>>>
>>>>>>>
>>>>>>>> On 31 Jan 2016, at 04:36, Carlo.Allocca <ca...@open.ac.uk> wrote:
>>>>>>>>
>>>>>>>> Dear Andy,
>>>>>>>>
>>>>>>>> Thank you very much one more time.
>>>>>>>>
>>>>>>>> Please, some comments follow in line.
>>>>>>>>
>>>>>>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>>>>>>
>>>>>>>> On 30/01/16 15:52, Carlo.Allocca wrote:
>>>>>>>> Hello Lorenz,
>>>>>>>>
>>>>>>>> Thank you for your help.
>>>>>>>>
>>>>>>>> It was clear to me that I have to remove from the parent expression and such is that using a patter-based approach
>>>>>>>> make it a bit difficult. I tried three of them and I got to the same results.
>>>>>>>>
>>>>>>>> You need to process the parent, not just the ElementFilter.
>>>>>>>>
>>>>>>>> How can I process the parent?
>>>>>>>> My understanding is:
>>>>>>>>
>>>>>>>> 1. Building the Abstract Query Tree: Op op = Algebra.compile(q);
>>>>>>>>
>>>>>>>> For example, given the query
>>>>>>>>
>>>>>>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>>>>>>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>>>>>>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>>>>>>>
>>>>>>>> SELECT DISTINCT ?ind ?boss ?g
>>>>>>>> WHERE
>>>>>>>> { { ?ind rdf:type ?z }
>>>>>>>> UNION
>>>>>>>> { ?boss ex:isBossOf ?ind
>>>>>>>> FILTER ( ?boss = "mathieu" )
>>>>>>>> }
>>>>>>>> }
>>>>>>>>
>>>>>>>> I obtain
>>>>>>>>
>>>>>>>> (distinct
>>>>>>>> (project (?ind ?boss ?g)
>>>>>>>> (union
>>>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>> (filter (= ?boss "mathieu")
>>>>>>>> (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))))))
>>>>>>>>
>>>>>>>> 2) Travere the tree to modify its internal structure. In terms of code, I can write:
>>>>>>>>
>>>>>>>> (A) Transform transform = new TransformRemoveOp(q,tp) ;
>>>>>>>> (B) op = Transformer.transform(transform, op);
>>>>>>>>
>>>>>>>> where TransformRemoveOp implements Transform interface.
>>>>>>>> It seems that there is no link between children and parent that can be used to figure out at which level the process is and modify the Tree structure, accordingly. Please correct me if I am wrong.
>>>>>>>> In fact running it over the above example, I got the following:
>>>>>>>>
>>>>>>>> =========== DURING
>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 1
>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>>
>>>>>>>>
>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 2
>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))
>>>>>>>>
>>>>>>>>
>>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty (bgp
>>>>>>>> )
>>>>>>>>
>>>>>>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter (filter (= ?boss "mathieu")
>>>>>>>> (bgp
>>>>>>>> ))
>>>>>>>>
>>>>>>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name bgp
>>>>>>>>
>>>>>>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] left: (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>>
>>>>>>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] right: (filter (exprlist (= ?boss "mathieu") true)
>>>>>>>> (bgp
>>>>>>>> ))
>>>>>>>>
>>>>>>>>
>>>>>>>> [TransformRemoveOp::transform(OpProject opProject, Op subOp)] (project (?ind ?boss ?g)
>>>>>>>> (union
>>>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>> (filter (exprlist (= ?boss "mathieu") true)
>>>>>>>> (bgp
>>>>>>>> ))))
>>>>>>>>
>>>>>>>>
>>>>>>>> [TransformRemoveOp::transform(OpDistinct opDistinct, Op subOp)] (distinct
>>>>>>>> (project (?ind ?boss ?g)
>>>>>>>> (union
>>>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>> (filter (exprlist (= ?boss "mathieu") true)
>>>>>>>> (bgp
>>>>>>>> )))))
>>>>>>>>
>>>>>>>>
>>>>>>>> Moreover, implementing a first version of the OpFilter as reported below:
>>>>>>>>
>>>>>>>> @Override
>>>>>>>> public Op transform(OpFilter opFilter, Op subOp) {
>>>>>>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter " + opFilter.toString());
>>>>>>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name " + subOp.getName());
>>>>>>>> System.out.println("");
>>>>>>>>
>>>>>>>> if (isParent == false) {
>>>>>>>> return opFilter;
>>>>>>>> }
>>>>>>>>
>>>>>>>> //...get the variables of the triple pattern that we want to delete
>>>>>>>> Set<Var> tpVars = new HashSet();
>>>>>>>> Node subj = this.triple.getSubject();
>>>>>>>> if (subj.isVariable()) {
>>>>>>>> tpVars.add((Var) subj);
>>>>>>>> }
>>>>>>>> Node pred = this.triple.getPredicate();
>>>>>>>> if (pred.isVariable()) {
>>>>>>>> tpVars.add((Var) pred);
>>>>>>>> }
>>>>>>>> Node obj = this.triple.getObject();
>>>>>>>> if (obj.isVariable()) {
>>>>>>>> tpVars.add((Var) obj);
>>>>>>>> }
>>>>>>>> //...get the variables of the FILTER expression
>>>>>>>> Op opNew = opFilter.copy(subOp);
>>>>>>>> Set<Var> expVars = ((OpFilter) opNew).getExprs().getVarsMentioned();
>>>>>>>>
>>>>>>>> //...check whether the FILTER expression contains any of the triple pattern variable
>>>>>>>> boolean isContained = false;
>>>>>>>> for (Var var : expVars) {
>>>>>>>> //..if it does then we have to delete the entire FILTER expression
>>>>>>>> if (tpVars.contains(var)) {
>>>>>>>> isContained = true;
>>>>>>>> break;
>>>>>>>> }
>>>>>>>> }
>>>>>>>> //... if the filter contains any variable of the triple that has been removed, then....
>>>>>>>> if (isContained) {
>>>>>>>> Op newOP;
>>>>>>>> Expr e;
>>>>>>>> if (subOp instanceof OpBGP) {
>>>>>>>> if (((OpBGP) subOp).getPattern().getList().isEmpty()) {
>>>>>>>> e = new NodeValueBoolean(true);
>>>>>>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>>>>>>> return newOP;
>>>>>>>> } else {
>>>>>>>> e = new NodeValueBoolean(false);
>>>>>>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>>>>>>> return newOP;
>>>>>>>> }
>>>>>>>> }
>>>>>>>> }
>>>>>>>> return opFilter;
>>>>>>>> }
>>>>>>>>
>>>>>>>> It produces the following SPARQL query:
>>>>>>>>
>>>>>>>> SELECT DISTINCT ?ind ?boss ?g
>>>>>>>> WHERE
>>>>>>>> { { ?ind a ?z }
>>>>>>>> UNION
>>>>>>>> { # Empty BGP
>>>>>>>>
>>>>>>>> FILTER ( ?boss = "mathieu" )
>>>>>>>> FILTER ( true )
>>>>>>>> }
>>>>>>>> }
>>>>>>>>
>>>>>>>> It seems quite challenging even transform the expression of "?boss = “mathieu” into “true” (as reported above) does not work as It should.
>>>>>>>>
>>>>>>>> If anyone could help me who is more experienced with this kind of task, I would be very very grateful.
>>>>>>>> I would like to see something concrete in sense of line of code as I am using.
>>>>>>>>
>>>>>>>> Many Thanks,
>>>>>>>> Best Regards,
>>>>>>>> Carlo
>>>>>>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>>>>>>
>>>>>>>> element has active parts
>>>>>>>>
>>>>>>>> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>>>>>>>
>>>>>> --
>>>>>> Lorenz Bühmann
>>>>>> AKSW group, University of Leipzig
>>>>>> Group: http://aksw.org - semantic web research center
>>>>>>
>>>>>
>>>>>
>>>> --
>>>> Lorenz Bühmann
>>>> AKSW group, University of Leipzig
>>>> Group: http://aksw.org - semantic web research center
>>>>
>>>
>>
>
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Dear Andy,
> On 31 Jan 2016, at 15:25, Andy Seaborne <an...@apache.org> wrote:
>
> Cleaning up is slightly easier in the syntax because BGPs and filters are inside a group (nothing to do with GROUP - a syntax group is things between {}.
>
> So when you want to delete something, have some custom Element class 'ElementDeleteMe' to return from the ElementFilter or ElementPathBlock. Something that can not appear in a legal query. it does not need to implement anything.
>
> Then in
> transform(ElementGroup el, List<Element> members) ;
>
> rewrite 'members' to remove any ElementDeleteMe.
>
> if members.size == 0
> return ElementDeleteMe
>
> so it recursive works.
>
> Take care at the top of syntax tree.
>
Thank you for the details.
It seems that I should be using org.apache.jena.sparql.syntax rather than org.apache.jena.sparql.algebra.
I will try to implement it as suggested above.
Many Thanks,
Best Regards,
Carlo
> Andy
>
> On 31/01/16 15:11, Carlo.Allocca wrote:
>> Hello Lorenz,
>>
>>
>> Sure no problem.
>> I can share it here. In case you have suggest any other place I will do so.
>>
>> Please, let me know.
>> Many Thanks,
>>
>> Best Regards,
>> Carlo
>>
>>> On 31 Jan 2016, at 15:07, Lorenz Bühmann <bu...@informatik.uni-leipzig.de> wrote:
>>>
>>> Hello Carlo,
>>>
>>> I'm sure you'll make it, but maybe you should also share the complete code somehow? Maybe this makes it easier for people to help you.
>>>
>>> Lorenz
>>>
>>>> Hello Lorenz,
>>>>
>>>> Thank you very much for your help.
>>>> Some comments follow in line.
>>>>
>>>>
>>>>> On 31 Jan 2016, at 13:36, Lorenz Bühmann <bu...@informatik.uni-leipzig.de> wrote:
>>>>>
>>>>> Hello Carlo,
>>>>>
>>>>> there is usually no link from a child node to its parent in the JENA data structures.
>>>> It is very good to confirm it as I don’t spend more time to look for it. I thought that I was missing some JENA data structure and packages.
>>>>
>>>>> That means you have to keep track of it when you're processing the parents. Why not run some "clean up" after each child has been processed? E.g. check if there is no BGP left and thus mark this current parent as also "toBeRemoved”.
>>>> Sure. I have already started doing it by using some boolean variables. Let’s see if I can make it.
>>>> Otherwise I have to develop a module that transform the Jena Query Expression into a Tree based representation and then apply the triple remove operation.
>>>>
>>>> Thank you again for your support and answers.
>>>>
>>>> Best Regards,
>>>> Carlo
>>>>
>>>>> Lorenz
>>>>>
>>>>>> and of course, the below is for processing an BGP:
>>>>>>
>>>>>> @Override
>>>>>> public Op transform(OpBGP opBGP) {
>>>>>>
>>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter " + opBGPCounter++);
>>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] " + opBGP.toString());
>>>>>> System.out.println("");
>>>>>> Op newOpBGP = opBGP.copy();
>>>>>> BasicPattern newBP = ((OpBGP) newOpBGP).getPattern();
>>>>>> List<Triple> tripleList = newBP.getList();
>>>>>>
>>>>>> Iterator<Triple> itr = tripleList.iterator();
>>>>>> while (itr.hasNext()) {
>>>>>> Triple tp = itr.next();
>>>>>> if (tp.matches(this.triple)) {
>>>>>> itr.remove();
>>>>>> isParent = true;
>>>>>> isStarted = true;
>>>>>> }
>>>>>> }
>>>>>> //...it can be empty
>>>>>> if (((OpBGP) newOpBGP).getPattern().getList().isEmpty()) {
>>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty " + opBGP.toString());
>>>>>> //return subOp;
>>>>>> }
>>>>>> return newOpBGP;
>>>>>> }
>>>>>>
>>>>>>
>>>>>> Many Thanks,
>>>>>> Carlo.
>>>>>>
>>>>>>
>>>>>>> On 31 Jan 2016, at 04:36, Carlo.Allocca <ca...@open.ac.uk> wrote:
>>>>>>>
>>>>>>> Dear Andy,
>>>>>>>
>>>>>>> Thank you very much one more time.
>>>>>>>
>>>>>>> Please, some comments follow in line.
>>>>>>>
>>>>>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>>>>>
>>>>>>> On 30/01/16 15:52, Carlo.Allocca wrote:
>>>>>>> Hello Lorenz,
>>>>>>>
>>>>>>> Thank you for your help.
>>>>>>>
>>>>>>> It was clear to me that I have to remove from the parent expression and such is that using a patter-based approach
>>>>>>> make it a bit difficult. I tried three of them and I got to the same results.
>>>>>>>
>>>>>>> You need to process the parent, not just the ElementFilter.
>>>>>>>
>>>>>>> How can I process the parent?
>>>>>>> My understanding is:
>>>>>>>
>>>>>>> 1. Building the Abstract Query Tree: Op op = Algebra.compile(q);
>>>>>>>
>>>>>>> For example, given the query
>>>>>>>
>>>>>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>>>>>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>>>>>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>>>>>>
>>>>>>> SELECT DISTINCT ?ind ?boss ?g
>>>>>>> WHERE
>>>>>>> { { ?ind rdf:type ?z }
>>>>>>> UNION
>>>>>>> { ?boss ex:isBossOf ?ind
>>>>>>> FILTER ( ?boss = "mathieu" )
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>> I obtain
>>>>>>>
>>>>>>> (distinct
>>>>>>> (project (?ind ?boss ?g)
>>>>>>> (union
>>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>> (filter (= ?boss "mathieu")
>>>>>>> (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))))))
>>>>>>>
>>>>>>> 2) Travere the tree to modify its internal structure. In terms of code, I can write:
>>>>>>>
>>>>>>> (A) Transform transform = new TransformRemoveOp(q,tp) ;
>>>>>>> (B) op = Transformer.transform(transform, op);
>>>>>>>
>>>>>>> where TransformRemoveOp implements Transform interface.
>>>>>>> It seems that there is no link between children and parent that can be used to figure out at which level the process is and modify the Tree structure, accordingly. Please correct me if I am wrong.
>>>>>>> In fact running it over the above example, I got the following:
>>>>>>>
>>>>>>> =========== DURING
>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 1
>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>
>>>>>>>
>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 2
>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))
>>>>>>>
>>>>>>>
>>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty (bgp
>>>>>>> )
>>>>>>>
>>>>>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter (filter (= ?boss "mathieu")
>>>>>>> (bgp
>>>>>>> ))
>>>>>>>
>>>>>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name bgp
>>>>>>>
>>>>>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] left: (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>>
>>>>>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] right: (filter (exprlist (= ?boss "mathieu") true)
>>>>>>> (bgp
>>>>>>> ))
>>>>>>>
>>>>>>>
>>>>>>> [TransformRemoveOp::transform(OpProject opProject, Op subOp)] (project (?ind ?boss ?g)
>>>>>>> (union
>>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>> (filter (exprlist (= ?boss "mathieu") true)
>>>>>>> (bgp
>>>>>>> ))))
>>>>>>>
>>>>>>>
>>>>>>> [TransformRemoveOp::transform(OpDistinct opDistinct, Op subOp)] (distinct
>>>>>>> (project (?ind ?boss ?g)
>>>>>>> (union
>>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>> (filter (exprlist (= ?boss "mathieu") true)
>>>>>>> (bgp
>>>>>>> )))))
>>>>>>>
>>>>>>>
>>>>>>> Moreover, implementing a first version of the OpFilter as reported below:
>>>>>>>
>>>>>>> @Override
>>>>>>> public Op transform(OpFilter opFilter, Op subOp) {
>>>>>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter " + opFilter.toString());
>>>>>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name " + subOp.getName());
>>>>>>> System.out.println("");
>>>>>>>
>>>>>>> if (isParent == false) {
>>>>>>> return opFilter;
>>>>>>> }
>>>>>>>
>>>>>>> //...get the variables of the triple pattern that we want to delete
>>>>>>> Set<Var> tpVars = new HashSet();
>>>>>>> Node subj = this.triple.getSubject();
>>>>>>> if (subj.isVariable()) {
>>>>>>> tpVars.add((Var) subj);
>>>>>>> }
>>>>>>> Node pred = this.triple.getPredicate();
>>>>>>> if (pred.isVariable()) {
>>>>>>> tpVars.add((Var) pred);
>>>>>>> }
>>>>>>> Node obj = this.triple.getObject();
>>>>>>> if (obj.isVariable()) {
>>>>>>> tpVars.add((Var) obj);
>>>>>>> }
>>>>>>> //...get the variables of the FILTER expression
>>>>>>> Op opNew = opFilter.copy(subOp);
>>>>>>> Set<Var> expVars = ((OpFilter) opNew).getExprs().getVarsMentioned();
>>>>>>>
>>>>>>> //...check whether the FILTER expression contains any of the triple pattern variable
>>>>>>> boolean isContained = false;
>>>>>>> for (Var var : expVars) {
>>>>>>> //..if it does then we have to delete the entire FILTER expression
>>>>>>> if (tpVars.contains(var)) {
>>>>>>> isContained = true;
>>>>>>> break;
>>>>>>> }
>>>>>>> }
>>>>>>> //... if the filter contains any variable of the triple that has been removed, then....
>>>>>>> if (isContained) {
>>>>>>> Op newOP;
>>>>>>> Expr e;
>>>>>>> if (subOp instanceof OpBGP) {
>>>>>>> if (((OpBGP) subOp).getPattern().getList().isEmpty()) {
>>>>>>> e = new NodeValueBoolean(true);
>>>>>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>>>>>> return newOP;
>>>>>>> } else {
>>>>>>> e = new NodeValueBoolean(false);
>>>>>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>>>>>> return newOP;
>>>>>>> }
>>>>>>> }
>>>>>>> }
>>>>>>> return opFilter;
>>>>>>> }
>>>>>>>
>>>>>>> It produces the following SPARQL query:
>>>>>>>
>>>>>>> SELECT DISTINCT ?ind ?boss ?g
>>>>>>> WHERE
>>>>>>> { { ?ind a ?z }
>>>>>>> UNION
>>>>>>> { # Empty BGP
>>>>>>>
>>>>>>> FILTER ( ?boss = "mathieu" )
>>>>>>> FILTER ( true )
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>> It seems quite challenging even transform the expression of "?boss = “mathieu” into “true” (as reported above) does not work as It should.
>>>>>>>
>>>>>>> If anyone could help me who is more experienced with this kind of task, I would be very very grateful.
>>>>>>> I would like to see something concrete in sense of line of code as I am using.
>>>>>>>
>>>>>>> Many Thanks,
>>>>>>> Best Regards,
>>>>>>> Carlo
>>>>>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>>>>>
>>>>>>> element has active parts
>>>>>>>
>>>>>>> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>>>>>>
>>>>> --
>>>>> Lorenz Bühmann
>>>>> AKSW group, University of Leipzig
>>>>> Group: http://aksw.org - semantic web research center
>>>>>
>>>>
>>>>
>>> --
>>> Lorenz Bühmann
>>> AKSW group, University of Leipzig
>>> Group: http://aksw.org - semantic web research center
>>>
>>
>
Re: How to remove consistently a triple pattern given a SPARQL query?
Posted by Andy Seaborne <an...@apache.org>.
Cleaning up is slightly easier in the syntax because BGPs and filters
are inside a group (nothing to do with GROUP - a syntax group is things
between {}.
So when you want to delete something, have some custom Element class
'ElementDeleteMe' to return from the ElementFilter or ElementPathBlock.
Something that can not appear in a legal query. it does not need to
implement anything.
Then in
transform(ElementGroup el, List<Element> members) ;
rewrite 'members' to remove any ElementDeleteMe.
if members.size == 0
return ElementDeleteMe
so it recursive works.
Take care at the top of syntax tree.
Andy
On 31/01/16 15:11, Carlo.Allocca wrote:
> Hello Lorenz,
>
>
> Sure no problem.
> I can share it here. In case you have suggest any other place I will do so.
>
> Please, let me know.
> Many Thanks,
>
> Best Regards,
> Carlo
>
>> On 31 Jan 2016, at 15:07, Lorenz Bühmann <bu...@informatik.uni-leipzig.de> wrote:
>>
>> Hello Carlo,
>>
>> I'm sure you'll make it, but maybe you should also share the complete code somehow? Maybe this makes it easier for people to help you.
>>
>> Lorenz
>>
>>> Hello Lorenz,
>>>
>>> Thank you very much for your help.
>>> Some comments follow in line.
>>>
>>>
>>>> On 31 Jan 2016, at 13:36, Lorenz Bühmann <bu...@informatik.uni-leipzig.de> wrote:
>>>>
>>>> Hello Carlo,
>>>>
>>>> there is usually no link from a child node to its parent in the JENA data structures.
>>> It is very good to confirm it as I don’t spend more time to look for it. I thought that I was missing some JENA data structure and packages.
>>>
>>>> That means you have to keep track of it when you're processing the parents. Why not run some "clean up" after each child has been processed? E.g. check if there is no BGP left and thus mark this current parent as also "toBeRemoved”.
>>> Sure. I have already started doing it by using some boolean variables. Let’s see if I can make it.
>>> Otherwise I have to develop a module that transform the Jena Query Expression into a Tree based representation and then apply the triple remove operation.
>>>
>>> Thank you again for your support and answers.
>>>
>>> Best Regards,
>>> Carlo
>>>
>>>> Lorenz
>>>>
>>>>> and of course, the below is for processing an BGP:
>>>>>
>>>>> @Override
>>>>> public Op transform(OpBGP opBGP) {
>>>>>
>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter " + opBGPCounter++);
>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] " + opBGP.toString());
>>>>> System.out.println("");
>>>>> Op newOpBGP = opBGP.copy();
>>>>> BasicPattern newBP = ((OpBGP) newOpBGP).getPattern();
>>>>> List<Triple> tripleList = newBP.getList();
>>>>>
>>>>> Iterator<Triple> itr = tripleList.iterator();
>>>>> while (itr.hasNext()) {
>>>>> Triple tp = itr.next();
>>>>> if (tp.matches(this.triple)) {
>>>>> itr.remove();
>>>>> isParent = true;
>>>>> isStarted = true;
>>>>> }
>>>>> }
>>>>> //...it can be empty
>>>>> if (((OpBGP) newOpBGP).getPattern().getList().isEmpty()) {
>>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty " + opBGP.toString());
>>>>> //return subOp;
>>>>> }
>>>>> return newOpBGP;
>>>>> }
>>>>>
>>>>>
>>>>> Many Thanks,
>>>>> Carlo.
>>>>>
>>>>>
>>>>>> On 31 Jan 2016, at 04:36, Carlo.Allocca <ca...@open.ac.uk> wrote:
>>>>>>
>>>>>> Dear Andy,
>>>>>>
>>>>>> Thank you very much one more time.
>>>>>>
>>>>>> Please, some comments follow in line.
>>>>>>
>>>>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>>>>
>>>>>> On 30/01/16 15:52, Carlo.Allocca wrote:
>>>>>> Hello Lorenz,
>>>>>>
>>>>>> Thank you for your help.
>>>>>>
>>>>>> It was clear to me that I have to remove from the parent expression and such is that using a patter-based approach
>>>>>> make it a bit difficult. I tried three of them and I got to the same results.
>>>>>>
>>>>>> You need to process the parent, not just the ElementFilter.
>>>>>>
>>>>>> How can I process the parent?
>>>>>> My understanding is:
>>>>>>
>>>>>> 1. Building the Abstract Query Tree: Op op = Algebra.compile(q);
>>>>>>
>>>>>> For example, given the query
>>>>>>
>>>>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>>>>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>>>>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>>>>>
>>>>>> SELECT DISTINCT ?ind ?boss ?g
>>>>>> WHERE
>>>>>> { { ?ind rdf:type ?z }
>>>>>> UNION
>>>>>> { ?boss ex:isBossOf ?ind
>>>>>> FILTER ( ?boss = "mathieu" )
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> I obtain
>>>>>>
>>>>>> (distinct
>>>>>> (project (?ind ?boss ?g)
>>>>>> (union
>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>> (filter (= ?boss "mathieu")
>>>>>> (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))))))
>>>>>>
>>>>>> 2) Travere the tree to modify its internal structure. In terms of code, I can write:
>>>>>>
>>>>>> (A) Transform transform = new TransformRemoveOp(q,tp) ;
>>>>>> (B) op = Transformer.transform(transform, op);
>>>>>>
>>>>>> where TransformRemoveOp implements Transform interface.
>>>>>> It seems that there is no link between children and parent that can be used to figure out at which level the process is and modify the Tree structure, accordingly. Please correct me if I am wrong.
>>>>>> In fact running it over the above example, I got the following:
>>>>>>
>>>>>> =========== DURING
>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 1
>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>
>>>>>>
>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 2
>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))
>>>>>>
>>>>>>
>>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty (bgp
>>>>>> )
>>>>>>
>>>>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter (filter (= ?boss "mathieu")
>>>>>> (bgp
>>>>>> ))
>>>>>>
>>>>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name bgp
>>>>>>
>>>>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] left: (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>>
>>>>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] right: (filter (exprlist (= ?boss "mathieu") true)
>>>>>> (bgp
>>>>>> ))
>>>>>>
>>>>>>
>>>>>> [TransformRemoveOp::transform(OpProject opProject, Op subOp)] (project (?ind ?boss ?g)
>>>>>> (union
>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>> (filter (exprlist (= ?boss "mathieu") true)
>>>>>> (bgp
>>>>>> ))))
>>>>>>
>>>>>>
>>>>>> [TransformRemoveOp::transform(OpDistinct opDistinct, Op subOp)] (distinct
>>>>>> (project (?ind ?boss ?g)
>>>>>> (union
>>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>> (filter (exprlist (= ?boss "mathieu") true)
>>>>>> (bgp
>>>>>> )))))
>>>>>>
>>>>>>
>>>>>> Moreover, implementing a first version of the OpFilter as reported below:
>>>>>>
>>>>>> @Override
>>>>>> public Op transform(OpFilter opFilter, Op subOp) {
>>>>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter " + opFilter.toString());
>>>>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name " + subOp.getName());
>>>>>> System.out.println("");
>>>>>>
>>>>>> if (isParent == false) {
>>>>>> return opFilter;
>>>>>> }
>>>>>>
>>>>>> //...get the variables of the triple pattern that we want to delete
>>>>>> Set<Var> tpVars = new HashSet();
>>>>>> Node subj = this.triple.getSubject();
>>>>>> if (subj.isVariable()) {
>>>>>> tpVars.add((Var) subj);
>>>>>> }
>>>>>> Node pred = this.triple.getPredicate();
>>>>>> if (pred.isVariable()) {
>>>>>> tpVars.add((Var) pred);
>>>>>> }
>>>>>> Node obj = this.triple.getObject();
>>>>>> if (obj.isVariable()) {
>>>>>> tpVars.add((Var) obj);
>>>>>> }
>>>>>> //...get the variables of the FILTER expression
>>>>>> Op opNew = opFilter.copy(subOp);
>>>>>> Set<Var> expVars = ((OpFilter) opNew).getExprs().getVarsMentioned();
>>>>>>
>>>>>> //...check whether the FILTER expression contains any of the triple pattern variable
>>>>>> boolean isContained = false;
>>>>>> for (Var var : expVars) {
>>>>>> //..if it does then we have to delete the entire FILTER expression
>>>>>> if (tpVars.contains(var)) {
>>>>>> isContained = true;
>>>>>> break;
>>>>>> }
>>>>>> }
>>>>>> //... if the filter contains any variable of the triple that has been removed, then....
>>>>>> if (isContained) {
>>>>>> Op newOP;
>>>>>> Expr e;
>>>>>> if (subOp instanceof OpBGP) {
>>>>>> if (((OpBGP) subOp).getPattern().getList().isEmpty()) {
>>>>>> e = new NodeValueBoolean(true);
>>>>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>>>>> return newOP;
>>>>>> } else {
>>>>>> e = new NodeValueBoolean(false);
>>>>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>>>>> return newOP;
>>>>>> }
>>>>>> }
>>>>>> }
>>>>>> return opFilter;
>>>>>> }
>>>>>>
>>>>>> It produces the following SPARQL query:
>>>>>>
>>>>>> SELECT DISTINCT ?ind ?boss ?g
>>>>>> WHERE
>>>>>> { { ?ind a ?z }
>>>>>> UNION
>>>>>> { # Empty BGP
>>>>>>
>>>>>> FILTER ( ?boss = "mathieu" )
>>>>>> FILTER ( true )
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> It seems quite challenging even transform the expression of "?boss = “mathieu” into “true” (as reported above) does not work as It should.
>>>>>>
>>>>>> If anyone could help me who is more experienced with this kind of task, I would be very very grateful.
>>>>>> I would like to see something concrete in sense of line of code as I am using.
>>>>>>
>>>>>> Many Thanks,
>>>>>> Best Regards,
>>>>>> Carlo
>>>>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>>>>
>>>>>> element has active parts
>>>>>>
>>>>>> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>>>>>
>>>> --
>>>> Lorenz Bühmann
>>>> AKSW group, University of Leipzig
>>>> Group: http://aksw.org - semantic web research center
>>>>
>>>
>>>
>> --
>> Lorenz Bühmann
>> AKSW group, University of Leipzig
>> Group: http://aksw.org - semantic web research center
>>
>
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Hello Lorenz,
Sure no problem.
I can share it here. In case you have suggest any other place I will do so.
Please, let me know.
Many Thanks,
Best Regards,
Carlo
> On 31 Jan 2016, at 15:07, Lorenz Bühmann <bu...@informatik.uni-leipzig.de> wrote:
>
> Hello Carlo,
>
> I'm sure you'll make it, but maybe you should also share the complete code somehow? Maybe this makes it easier for people to help you.
>
> Lorenz
>
>> Hello Lorenz,
>>
>> Thank you very much for your help.
>> Some comments follow in line.
>>
>>
>>> On 31 Jan 2016, at 13:36, Lorenz Bühmann <bu...@informatik.uni-leipzig.de> wrote:
>>>
>>> Hello Carlo,
>>>
>>> there is usually no link from a child node to its parent in the JENA data structures.
>> It is very good to confirm it as I don’t spend more time to look for it. I thought that I was missing some JENA data structure and packages.
>>
>>> That means you have to keep track of it when you're processing the parents. Why not run some "clean up" after each child has been processed? E.g. check if there is no BGP left and thus mark this current parent as also "toBeRemoved”.
>> Sure. I have already started doing it by using some boolean variables. Let’s see if I can make it.
>> Otherwise I have to develop a module that transform the Jena Query Expression into a Tree based representation and then apply the triple remove operation.
>>
>> Thank you again for your support and answers.
>>
>> Best Regards,
>> Carlo
>>
>>> Lorenz
>>>
>>>> and of course, the below is for processing an BGP:
>>>>
>>>> @Override
>>>> public Op transform(OpBGP opBGP) {
>>>>
>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter " + opBGPCounter++);
>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] " + opBGP.toString());
>>>> System.out.println("");
>>>> Op newOpBGP = opBGP.copy();
>>>> BasicPattern newBP = ((OpBGP) newOpBGP).getPattern();
>>>> List<Triple> tripleList = newBP.getList();
>>>>
>>>> Iterator<Triple> itr = tripleList.iterator();
>>>> while (itr.hasNext()) {
>>>> Triple tp = itr.next();
>>>> if (tp.matches(this.triple)) {
>>>> itr.remove();
>>>> isParent = true;
>>>> isStarted = true;
>>>> }
>>>> }
>>>> //...it can be empty
>>>> if (((OpBGP) newOpBGP).getPattern().getList().isEmpty()) {
>>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty " + opBGP.toString());
>>>> //return subOp;
>>>> }
>>>> return newOpBGP;
>>>> }
>>>>
>>>>
>>>> Many Thanks,
>>>> Carlo.
>>>>
>>>>
>>>>> On 31 Jan 2016, at 04:36, Carlo.Allocca <ca...@open.ac.uk> wrote:
>>>>>
>>>>> Dear Andy,
>>>>>
>>>>> Thank you very much one more time.
>>>>>
>>>>> Please, some comments follow in line.
>>>>>
>>>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>>>
>>>>> On 30/01/16 15:52, Carlo.Allocca wrote:
>>>>> Hello Lorenz,
>>>>>
>>>>> Thank you for your help.
>>>>>
>>>>> It was clear to me that I have to remove from the parent expression and such is that using a patter-based approach
>>>>> make it a bit difficult. I tried three of them and I got to the same results.
>>>>>
>>>>> You need to process the parent, not just the ElementFilter.
>>>>>
>>>>> How can I process the parent?
>>>>> My understanding is:
>>>>>
>>>>> 1. Building the Abstract Query Tree: Op op = Algebra.compile(q);
>>>>>
>>>>> For example, given the query
>>>>>
>>>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>>>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>>>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>>>>
>>>>> SELECT DISTINCT ?ind ?boss ?g
>>>>> WHERE
>>>>> { { ?ind rdf:type ?z }
>>>>> UNION
>>>>> { ?boss ex:isBossOf ?ind
>>>>> FILTER ( ?boss = "mathieu" )
>>>>> }
>>>>> }
>>>>>
>>>>> I obtain
>>>>>
>>>>> (distinct
>>>>> (project (?ind ?boss ?g)
>>>>> (union
>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>> (filter (= ?boss "mathieu")
>>>>> (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))))))
>>>>>
>>>>> 2) Travere the tree to modify its internal structure. In terms of code, I can write:
>>>>>
>>>>> (A) Transform transform = new TransformRemoveOp(q,tp) ;
>>>>> (B) op = Transformer.transform(transform, op);
>>>>>
>>>>> where TransformRemoveOp implements Transform interface.
>>>>> It seems that there is no link between children and parent that can be used to figure out at which level the process is and modify the Tree structure, accordingly. Please correct me if I am wrong.
>>>>> In fact running it over the above example, I got the following:
>>>>>
>>>>> =========== DURING
>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 1
>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>
>>>>>
>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 2
>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))
>>>>>
>>>>>
>>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty (bgp
>>>>> )
>>>>>
>>>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter (filter (= ?boss "mathieu")
>>>>> (bgp
>>>>> ))
>>>>>
>>>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name bgp
>>>>>
>>>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] left: (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>>
>>>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] right: (filter (exprlist (= ?boss "mathieu") true)
>>>>> (bgp
>>>>> ))
>>>>>
>>>>>
>>>>> [TransformRemoveOp::transform(OpProject opProject, Op subOp)] (project (?ind ?boss ?g)
>>>>> (union
>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>> (filter (exprlist (= ?boss "mathieu") true)
>>>>> (bgp
>>>>> ))))
>>>>>
>>>>>
>>>>> [TransformRemoveOp::transform(OpDistinct opDistinct, Op subOp)] (distinct
>>>>> (project (?ind ?boss ?g)
>>>>> (union
>>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>> (filter (exprlist (= ?boss "mathieu") true)
>>>>> (bgp
>>>>> )))))
>>>>>
>>>>>
>>>>> Moreover, implementing a first version of the OpFilter as reported below:
>>>>>
>>>>> @Override
>>>>> public Op transform(OpFilter opFilter, Op subOp) {
>>>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter " + opFilter.toString());
>>>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name " + subOp.getName());
>>>>> System.out.println("");
>>>>>
>>>>> if (isParent == false) {
>>>>> return opFilter;
>>>>> }
>>>>>
>>>>> //...get the variables of the triple pattern that we want to delete
>>>>> Set<Var> tpVars = new HashSet();
>>>>> Node subj = this.triple.getSubject();
>>>>> if (subj.isVariable()) {
>>>>> tpVars.add((Var) subj);
>>>>> }
>>>>> Node pred = this.triple.getPredicate();
>>>>> if (pred.isVariable()) {
>>>>> tpVars.add((Var) pred);
>>>>> }
>>>>> Node obj = this.triple.getObject();
>>>>> if (obj.isVariable()) {
>>>>> tpVars.add((Var) obj);
>>>>> }
>>>>> //...get the variables of the FILTER expression
>>>>> Op opNew = opFilter.copy(subOp);
>>>>> Set<Var> expVars = ((OpFilter) opNew).getExprs().getVarsMentioned();
>>>>>
>>>>> //...check whether the FILTER expression contains any of the triple pattern variable
>>>>> boolean isContained = false;
>>>>> for (Var var : expVars) {
>>>>> //..if it does then we have to delete the entire FILTER expression
>>>>> if (tpVars.contains(var)) {
>>>>> isContained = true;
>>>>> break;
>>>>> }
>>>>> }
>>>>> //... if the filter contains any variable of the triple that has been removed, then....
>>>>> if (isContained) {
>>>>> Op newOP;
>>>>> Expr e;
>>>>> if (subOp instanceof OpBGP) {
>>>>> if (((OpBGP) subOp).getPattern().getList().isEmpty()) {
>>>>> e = new NodeValueBoolean(true);
>>>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>>>> return newOP;
>>>>> } else {
>>>>> e = new NodeValueBoolean(false);
>>>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>>>> return newOP;
>>>>> }
>>>>> }
>>>>> }
>>>>> return opFilter;
>>>>> }
>>>>>
>>>>> It produces the following SPARQL query:
>>>>>
>>>>> SELECT DISTINCT ?ind ?boss ?g
>>>>> WHERE
>>>>> { { ?ind a ?z }
>>>>> UNION
>>>>> { # Empty BGP
>>>>>
>>>>> FILTER ( ?boss = "mathieu" )
>>>>> FILTER ( true )
>>>>> }
>>>>> }
>>>>>
>>>>> It seems quite challenging even transform the expression of "?boss = “mathieu” into “true” (as reported above) does not work as It should.
>>>>>
>>>>> If anyone could help me who is more experienced with this kind of task, I would be very very grateful.
>>>>> I would like to see something concrete in sense of line of code as I am using.
>>>>>
>>>>> Many Thanks,
>>>>> Best Regards,
>>>>> Carlo
>>>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>>>
>>>>> element has active parts
>>>>>
>>>>> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>>>>
>>> --
>>> Lorenz Bühmann
>>> AKSW group, University of Leipzig
>>> Group: http://aksw.org - semantic web research center
>>>
>>
>>
> --
> Lorenz Bühmann
> AKSW group, University of Leipzig
> Group: http://aksw.org - semantic web research center
>
Re: How to remove consistently a triple pattern given a SPARQL query?
Posted by Lorenz Bühmann <bu...@informatik.uni-leipzig.de>.
Hello Carlo,
I'm sure you'll make it, but maybe you should also share the complete
code somehow? Maybe this makes it easier for people to help you.
Lorenz
> Hello Lorenz,
>
> Thank you very much for your help.
> Some comments follow in line.
>
>
>> On 31 Jan 2016, at 13:36, Lorenz Bühmann <bu...@informatik.uni-leipzig.de> wrote:
>>
>> Hello Carlo,
>>
>> there is usually no link from a child node to its parent in the JENA data structures.
> It is very good to confirm it as I don’t spend more time to look for it. I thought that I was missing some JENA data structure and packages.
>
>> That means you have to keep track of it when you're processing the parents. Why not run some "clean up" after each child has been processed? E.g. check if there is no BGP left and thus mark this current parent as also "toBeRemoved”.
> Sure. I have already started doing it by using some boolean variables. Let’s see if I can make it.
> Otherwise I have to develop a module that transform the Jena Query Expression into a Tree based representation and then apply the triple remove operation.
>
> Thank you again for your support and answers.
>
> Best Regards,
> Carlo
>
>> Lorenz
>>
>>> and of course, the below is for processing an BGP:
>>>
>>> @Override
>>> public Op transform(OpBGP opBGP) {
>>>
>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter " + opBGPCounter++);
>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] " + opBGP.toString());
>>> System.out.println("");
>>> Op newOpBGP = opBGP.copy();
>>> BasicPattern newBP = ((OpBGP) newOpBGP).getPattern();
>>> List<Triple> tripleList = newBP.getList();
>>>
>>> Iterator<Triple> itr = tripleList.iterator();
>>> while (itr.hasNext()) {
>>> Triple tp = itr.next();
>>> if (tp.matches(this.triple)) {
>>> itr.remove();
>>> isParent = true;
>>> isStarted = true;
>>> }
>>> }
>>> //...it can be empty
>>> if (((OpBGP) newOpBGP).getPattern().getList().isEmpty()) {
>>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty " + opBGP.toString());
>>> //return subOp;
>>> }
>>> return newOpBGP;
>>> }
>>>
>>>
>>> Many Thanks,
>>> Carlo.
>>>
>>>
>>>> On 31 Jan 2016, at 04:36, Carlo.Allocca <ca...@open.ac.uk> wrote:
>>>>
>>>> Dear Andy,
>>>>
>>>> Thank you very much one more time.
>>>>
>>>> Please, some comments follow in line.
>>>>
>>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>>
>>>> On 30/01/16 15:52, Carlo.Allocca wrote:
>>>> Hello Lorenz,
>>>>
>>>> Thank you for your help.
>>>>
>>>> It was clear to me that I have to remove from the parent expression and such is that using a patter-based approach
>>>> make it a bit difficult. I tried three of them and I got to the same results.
>>>>
>>>> You need to process the parent, not just the ElementFilter.
>>>>
>>>> How can I process the parent?
>>>> My understanding is:
>>>>
>>>> 1. Building the Abstract Query Tree: Op op = Algebra.compile(q);
>>>>
>>>> For example, given the query
>>>>
>>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>>>
>>>> SELECT DISTINCT ?ind ?boss ?g
>>>> WHERE
>>>> { { ?ind rdf:type ?z }
>>>> UNION
>>>> { ?boss ex:isBossOf ?ind
>>>> FILTER ( ?boss = "mathieu" )
>>>> }
>>>> }
>>>>
>>>> I obtain
>>>>
>>>> (distinct
>>>> (project (?ind ?boss ?g)
>>>> (union
>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>> (filter (= ?boss "mathieu")
>>>> (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))))))
>>>>
>>>> 2) Travere the tree to modify its internal structure. In terms of code, I can write:
>>>>
>>>> (A) Transform transform = new TransformRemoveOp(q,tp) ;
>>>> (B) op = Transformer.transform(transform, op);
>>>>
>>>> where TransformRemoveOp implements Transform interface.
>>>> It seems that there is no link between children and parent that can be used to figure out at which level the process is and modify the Tree structure, accordingly. Please correct me if I am wrong.
>>>> In fact running it over the above example, I got the following:
>>>>
>>>> =========== DURING
>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 1
>>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>
>>>>
>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 2
>>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))
>>>>
>>>>
>>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty (bgp
>>>> )
>>>>
>>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter (filter (= ?boss "mathieu")
>>>> (bgp
>>>> ))
>>>>
>>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name bgp
>>>>
>>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] left: (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>>
>>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] right: (filter (exprlist (= ?boss "mathieu") true)
>>>> (bgp
>>>> ))
>>>>
>>>>
>>>> [TransformRemoveOp::transform(OpProject opProject, Op subOp)] (project (?ind ?boss ?g)
>>>> (union
>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>> (filter (exprlist (= ?boss "mathieu") true)
>>>> (bgp
>>>> ))))
>>>>
>>>>
>>>> [TransformRemoveOp::transform(OpDistinct opDistinct, Op subOp)] (distinct
>>>> (project (?ind ?boss ?g)
>>>> (union
>>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>> (filter (exprlist (= ?boss "mathieu") true)
>>>> (bgp
>>>> )))))
>>>>
>>>>
>>>> Moreover, implementing a first version of the OpFilter as reported below:
>>>>
>>>> @Override
>>>> public Op transform(OpFilter opFilter, Op subOp) {
>>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter " + opFilter.toString());
>>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name " + subOp.getName());
>>>> System.out.println("");
>>>>
>>>> if (isParent == false) {
>>>> return opFilter;
>>>> }
>>>>
>>>> //...get the variables of the triple pattern that we want to delete
>>>> Set<Var> tpVars = new HashSet();
>>>> Node subj = this.triple.getSubject();
>>>> if (subj.isVariable()) {
>>>> tpVars.add((Var) subj);
>>>> }
>>>> Node pred = this.triple.getPredicate();
>>>> if (pred.isVariable()) {
>>>> tpVars.add((Var) pred);
>>>> }
>>>> Node obj = this.triple.getObject();
>>>> if (obj.isVariable()) {
>>>> tpVars.add((Var) obj);
>>>> }
>>>> //...get the variables of the FILTER expression
>>>> Op opNew = opFilter.copy(subOp);
>>>> Set<Var> expVars = ((OpFilter) opNew).getExprs().getVarsMentioned();
>>>>
>>>> //...check whether the FILTER expression contains any of the triple pattern variable
>>>> boolean isContained = false;
>>>> for (Var var : expVars) {
>>>> //..if it does then we have to delete the entire FILTER expression
>>>> if (tpVars.contains(var)) {
>>>> isContained = true;
>>>> break;
>>>> }
>>>> }
>>>> //... if the filter contains any variable of the triple that has been removed, then....
>>>> if (isContained) {
>>>> Op newOP;
>>>> Expr e;
>>>> if (subOp instanceof OpBGP) {
>>>> if (((OpBGP) subOp).getPattern().getList().isEmpty()) {
>>>> e = new NodeValueBoolean(true);
>>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>>> return newOP;
>>>> } else {
>>>> e = new NodeValueBoolean(false);
>>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>>> return newOP;
>>>> }
>>>> }
>>>> }
>>>> return opFilter;
>>>> }
>>>>
>>>> It produces the following SPARQL query:
>>>>
>>>> SELECT DISTINCT ?ind ?boss ?g
>>>> WHERE
>>>> { { ?ind a ?z }
>>>> UNION
>>>> { # Empty BGP
>>>>
>>>> FILTER ( ?boss = "mathieu" )
>>>> FILTER ( true )
>>>> }
>>>> }
>>>>
>>>> It seems quite challenging even transform the expression of "?boss = “mathieu” into “true” (as reported above) does not work as It should.
>>>>
>>>> If anyone could help me who is more experienced with this kind of task, I would be very very grateful.
>>>> I would like to see something concrete in sense of line of code as I am using.
>>>>
>>>> Many Thanks,
>>>> Best Regards,
>>>> Carlo
>>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>>
>>>> element has active parts
>>>>
>>>> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>>>
>> --
>> Lorenz Bühmann
>> AKSW group, University of Leipzig
>> Group: http://aksw.org - semantic web research center
>>
>
>
--
Lorenz Bühmann
AKSW group, University of Leipzig
Group: http://aksw.org - semantic web research center
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Hello Lorenz,
Thank you very much for your help.
Some comments follow in line.
> On 31 Jan 2016, at 13:36, Lorenz Bühmann <bu...@informatik.uni-leipzig.de> wrote:
>
> Hello Carlo,
>
> there is usually no link from a child node to its parent in the JENA data structures.
It is very good to confirm it as I don’t spend more time to look for it. I thought that I was missing some JENA data structure and packages.
> That means you have to keep track of it when you're processing the parents. Why not run some "clean up" after each child has been processed? E.g. check if there is no BGP left and thus mark this current parent as also "toBeRemoved”.
Sure. I have already started doing it by using some boolean variables. Let’s see if I can make it.
Otherwise I have to develop a module that transform the Jena Query Expression into a Tree based representation and then apply the triple remove operation.
Thank you again for your support and answers.
Best Regards,
Carlo
>
> Lorenz
>
>> and of course, the below is for processing an BGP:
>>
>> @Override
>> public Op transform(OpBGP opBGP) {
>>
>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter " + opBGPCounter++);
>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] " + opBGP.toString());
>> System.out.println("");
>> Op newOpBGP = opBGP.copy();
>> BasicPattern newBP = ((OpBGP) newOpBGP).getPattern();
>> List<Triple> tripleList = newBP.getList();
>>
>> Iterator<Triple> itr = tripleList.iterator();
>> while (itr.hasNext()) {
>> Triple tp = itr.next();
>> if (tp.matches(this.triple)) {
>> itr.remove();
>> isParent = true;
>> isStarted = true;
>> }
>> }
>> //...it can be empty
>> if (((OpBGP) newOpBGP).getPattern().getList().isEmpty()) {
>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty " + opBGP.toString());
>> //return subOp;
>> }
>> return newOpBGP;
>> }
>>
>>
>> Many Thanks,
>> Carlo.
>>
>>
>>> On 31 Jan 2016, at 04:36, Carlo.Allocca <ca...@open.ac.uk> wrote:
>>>
>>> Dear Andy,
>>>
>>> Thank you very much one more time.
>>>
>>> Please, some comments follow in line.
>>>
>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>
>>> On 30/01/16 15:52, Carlo.Allocca wrote:
>>> Hello Lorenz,
>>>
>>> Thank you for your help.
>>>
>>> It was clear to me that I have to remove from the parent expression and such is that using a patter-based approach
>>> make it a bit difficult. I tried three of them and I got to the same results.
>>>
>>> You need to process the parent, not just the ElementFilter.
>>>
>>> How can I process the parent?
>>> My understanding is:
>>>
>>> 1. Building the Abstract Query Tree: Op op = Algebra.compile(q);
>>>
>>> For example, given the query
>>>
>>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>>
>>> SELECT DISTINCT ?ind ?boss ?g
>>> WHERE
>>> { { ?ind rdf:type ?z }
>>> UNION
>>> { ?boss ex:isBossOf ?ind
>>> FILTER ( ?boss = "mathieu" )
>>> }
>>> }
>>>
>>> I obtain
>>>
>>> (distinct
>>> (project (?ind ?boss ?g)
>>> (union
>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>> (filter (= ?boss "mathieu")
>>> (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))))))
>>>
>>> 2) Travere the tree to modify its internal structure. In terms of code, I can write:
>>>
>>> (A) Transform transform = new TransformRemoveOp(q,tp) ;
>>> (B) op = Transformer.transform(transform, op);
>>>
>>> where TransformRemoveOp implements Transform interface.
>>> It seems that there is no link between children and parent that can be used to figure out at which level the process is and modify the Tree structure, accordingly. Please correct me if I am wrong.
>>> In fact running it over the above example, I got the following:
>>>
>>> =========== DURING
>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 1
>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>
>>>
>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 2
>>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))
>>>
>>>
>>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty (bgp
>>> )
>>>
>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter (filter (= ?boss "mathieu")
>>> (bgp
>>> ))
>>>
>>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name bgp
>>>
>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] left: (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>>
>>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] right: (filter (exprlist (= ?boss "mathieu") true)
>>> (bgp
>>> ))
>>>
>>>
>>> [TransformRemoveOp::transform(OpProject opProject, Op subOp)] (project (?ind ?boss ?g)
>>> (union
>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>> (filter (exprlist (= ?boss "mathieu") true)
>>> (bgp
>>> ))))
>>>
>>>
>>> [TransformRemoveOp::transform(OpDistinct opDistinct, Op subOp)] (distinct
>>> (project (?ind ?boss ?g)
>>> (union
>>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>> (filter (exprlist (= ?boss "mathieu") true)
>>> (bgp
>>> )))))
>>>
>>>
>>> Moreover, implementing a first version of the OpFilter as reported below:
>>>
>>> @Override
>>> public Op transform(OpFilter opFilter, Op subOp) {
>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter " + opFilter.toString());
>>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name " + subOp.getName());
>>> System.out.println("");
>>>
>>> if (isParent == false) {
>>> return opFilter;
>>> }
>>>
>>> //...get the variables of the triple pattern that we want to delete
>>> Set<Var> tpVars = new HashSet();
>>> Node subj = this.triple.getSubject();
>>> if (subj.isVariable()) {
>>> tpVars.add((Var) subj);
>>> }
>>> Node pred = this.triple.getPredicate();
>>> if (pred.isVariable()) {
>>> tpVars.add((Var) pred);
>>> }
>>> Node obj = this.triple.getObject();
>>> if (obj.isVariable()) {
>>> tpVars.add((Var) obj);
>>> }
>>> //...get the variables of the FILTER expression
>>> Op opNew = opFilter.copy(subOp);
>>> Set<Var> expVars = ((OpFilter) opNew).getExprs().getVarsMentioned();
>>>
>>> //...check whether the FILTER expression contains any of the triple pattern variable
>>> boolean isContained = false;
>>> for (Var var : expVars) {
>>> //..if it does then we have to delete the entire FILTER expression
>>> if (tpVars.contains(var)) {
>>> isContained = true;
>>> break;
>>> }
>>> }
>>> //... if the filter contains any variable of the triple that has been removed, then....
>>> if (isContained) {
>>> Op newOP;
>>> Expr e;
>>> if (subOp instanceof OpBGP) {
>>> if (((OpBGP) subOp).getPattern().getList().isEmpty()) {
>>> e = new NodeValueBoolean(true);
>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>> return newOP;
>>> } else {
>>> e = new NodeValueBoolean(false);
>>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>>> return newOP;
>>> }
>>> }
>>> }
>>> return opFilter;
>>> }
>>>
>>> It produces the following SPARQL query:
>>>
>>> SELECT DISTINCT ?ind ?boss ?g
>>> WHERE
>>> { { ?ind a ?z }
>>> UNION
>>> { # Empty BGP
>>>
>>> FILTER ( ?boss = "mathieu" )
>>> FILTER ( true )
>>> }
>>> }
>>>
>>> It seems quite challenging even transform the expression of "?boss = “mathieu” into “true” (as reported above) does not work as It should.
>>>
>>> If anyone could help me who is more experienced with this kind of task, I would be very very grateful.
>>> I would like to see something concrete in sense of line of code as I am using.
>>>
>>> Many Thanks,
>>> Best Regards,
>>> Carlo
>>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>>
>>> element has active parts
>>>
>>> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>>
>>
> --
> Lorenz Bühmann
> AKSW group, University of Leipzig
> Group: http://aksw.org - semantic web research center
>
Re: How to remove consistently a triple pattern given a SPARQL query?
Posted by Lorenz Bühmann <bu...@informatik.uni-leipzig.de>.
Hello Carlo,
there is usually no link from a child node to its parent in the JENA
datastructures. That means you have to keep track of it when you're
processing the parents. Why not run some "clean up" after each child has
been processed? E.g. check if there is no BGP left and thus mark this
current parent as also "toBeRemoved".
Lorenz
> and of course, the below is for processing an BGP:
>
> @Override
> public Op transform(OpBGP opBGP) {
>
> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter " + opBGPCounter++);
> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] " + opBGP.toString());
> System.out.println("");
> Op newOpBGP = opBGP.copy();
> BasicPattern newBP = ((OpBGP) newOpBGP).getPattern();
> List<Triple> tripleList = newBP.getList();
>
> Iterator<Triple> itr = tripleList.iterator();
> while (itr.hasNext()) {
> Triple tp = itr.next();
> if (tp.matches(this.triple)) {
> itr.remove();
> isParent = true;
> isStarted = true;
> }
> }
> //...it can be empty
> if (((OpBGP) newOpBGP).getPattern().getList().isEmpty()) {
> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty " + opBGP.toString());
> //return subOp;
> }
> return newOpBGP;
> }
>
>
> Many Thanks,
> Carlo.
>
>
>> On 31 Jan 2016, at 04:36, Carlo.Allocca <ca...@open.ac.uk> wrote:
>>
>> Dear Andy,
>>
>> Thank you very much one more time.
>>
>> Please, some comments follow in line.
>>
>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>
>> On 30/01/16 15:52, Carlo.Allocca wrote:
>> Hello Lorenz,
>>
>> Thank you for your help.
>>
>> It was clear to me that I have to remove from the parent expression and such is that using a patter-based approach
>> make it a bit difficult. I tried three of them and I got to the same results.
>>
>> You need to process the parent, not just the ElementFilter.
>>
>> How can I process the parent?
>> My understanding is:
>>
>> 1. Building the Abstract Query Tree: Op op = Algebra.compile(q);
>>
>> For example, given the query
>>
>> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
>> PREFIX ex: <http://www.semanticweb.org/dataset1/>
>> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>>
>> SELECT DISTINCT ?ind ?boss ?g
>> WHERE
>> { { ?ind rdf:type ?z }
>> UNION
>> { ?boss ex:isBossOf ?ind
>> FILTER ( ?boss = "mathieu" )
>> }
>> }
>>
>> I obtain
>>
>> (distinct
>> (project (?ind ?boss ?g)
>> (union
>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>> (filter (= ?boss "mathieu")
>> (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))))))
>>
>> 2) Travere the tree to modify its internal structure. In terms of code, I can write:
>>
>> (A) Transform transform = new TransformRemoveOp(q,tp) ;
>> (B) op = Transformer.transform(transform, op);
>>
>> where TransformRemoveOp implements Transform interface.
>> It seems that there is no link between children and parent that can be used to figure out at which level the process is and modify the Tree structure, accordingly. Please correct me if I am wrong.
>> In fact running it over the above example, I got the following:
>>
>> =========== DURING
>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 1
>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>
>>
>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 2
>> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))
>>
>>
>> [TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty (bgp
>> )
>>
>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter (filter (= ?boss "mathieu")
>> (bgp
>> ))
>>
>> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name bgp
>>
>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] left: (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>>
>> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] right: (filter (exprlist (= ?boss "mathieu") true)
>> (bgp
>> ))
>>
>>
>> [TransformRemoveOp::transform(OpProject opProject, Op subOp)] (project (?ind ?boss ?g)
>> (union
>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>> (filter (exprlist (= ?boss "mathieu") true)
>> (bgp
>> ))))
>>
>>
>> [TransformRemoveOp::transform(OpDistinct opDistinct, Op subOp)] (distinct
>> (project (?ind ?boss ?g)
>> (union
>> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>> (filter (exprlist (= ?boss "mathieu") true)
>> (bgp
>> )))))
>>
>>
>> Moreover, implementing a first version of the OpFilter as reported below:
>>
>> @Override
>> public Op transform(OpFilter opFilter, Op subOp) {
>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter " + opFilter.toString());
>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name " + subOp.getName());
>> System.out.println("");
>>
>> if (isParent == false) {
>> return opFilter;
>> }
>>
>> //...get the variables of the triple pattern that we want to delete
>> Set<Var> tpVars = new HashSet();
>> Node subj = this.triple.getSubject();
>> if (subj.isVariable()) {
>> tpVars.add((Var) subj);
>> }
>> Node pred = this.triple.getPredicate();
>> if (pred.isVariable()) {
>> tpVars.add((Var) pred);
>> }
>> Node obj = this.triple.getObject();
>> if (obj.isVariable()) {
>> tpVars.add((Var) obj);
>> }
>> //...get the variables of the FILTER expression
>> Op opNew = opFilter.copy(subOp);
>> Set<Var> expVars = ((OpFilter) opNew).getExprs().getVarsMentioned();
>>
>> //...check whether the FILTER expression contains any of the triple pattern variable
>> boolean isContained = false;
>> for (Var var : expVars) {
>> //..if it does then we have to delete the entire FILTER expression
>> if (tpVars.contains(var)) {
>> isContained = true;
>> break;
>> }
>> }
>> //... if the filter contains any variable of the triple that has been removed, then....
>> if (isContained) {
>> Op newOP;
>> Expr e;
>> if (subOp instanceof OpBGP) {
>> if (((OpBGP) subOp).getPattern().getList().isEmpty()) {
>> e = new NodeValueBoolean(true);
>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>> return newOP;
>> } else {
>> e = new NodeValueBoolean(false);
>> newOP = OpFilter.filter(e, opFilter);//filter(e, );
>> return newOP;
>> }
>> }
>> }
>> return opFilter;
>> }
>>
>> It produces the following SPARQL query:
>>
>> SELECT DISTINCT ?ind ?boss ?g
>> WHERE
>> { { ?ind a ?z }
>> UNION
>> { # Empty BGP
>>
>> FILTER ( ?boss = "mathieu" )
>> FILTER ( true )
>> }
>> }
>>
>> It seems quite challenging even transform the expression of "?boss = “mathieu” into “true” (as reported above) does not work as It should.
>>
>> If anyone could help me who is more experienced with this kind of task, I would be very very grateful.
>> I would like to see something concrete in sense of line of code as I am using.
>>
>> Many Thanks,
>> Best Regards,
>> Carlo
>> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>>
>> element has active parts
>>
>> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>
>
--
Lorenz Bühmann
AKSW group, University of Leipzig
Group: http://aksw.org - semantic web research center
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
and of course, the below is for processing an BGP:
@Override
public Op transform(OpBGP opBGP) {
System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter " + opBGPCounter++);
System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] " + opBGP.toString());
System.out.println("");
Op newOpBGP = opBGP.copy();
BasicPattern newBP = ((OpBGP) newOpBGP).getPattern();
List<Triple> tripleList = newBP.getList();
Iterator<Triple> itr = tripleList.iterator();
while (itr.hasNext()) {
Triple tp = itr.next();
if (tp.matches(this.triple)) {
itr.remove();
isParent = true;
isStarted = true;
}
}
//...it can be empty
if (((OpBGP) newOpBGP).getPattern().getList().isEmpty()) {
System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty " + opBGP.toString());
//return subOp;
}
return newOpBGP;
}
Many Thanks,
Carlo.
> On 31 Jan 2016, at 04:36, Carlo.Allocca <ca...@open.ac.uk> wrote:
>
> Dear Andy,
>
> Thank you very much one more time.
>
> Please, some comments follow in line.
>
> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>
> On 30/01/16 15:52, Carlo.Allocca wrote:
> Hello Lorenz,
>
> Thank you for your help.
>
> It was clear to me that I have to remove from the parent expression and such is that using a patter-based approach
> make it a bit difficult. I tried three of them and I got to the same results.
>
> You need to process the parent, not just the ElementFilter.
>
> How can I process the parent?
> My understanding is:
>
> 1. Building the Abstract Query Tree: Op op = Algebra.compile(q);
>
> For example, given the query
>
> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
> PREFIX ex: <http://www.semanticweb.org/dataset1/>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind rdf:type ?z }
> UNION
> { ?boss ex:isBossOf ?ind
> FILTER ( ?boss = "mathieu" )
> }
> }
>
> I obtain
>
> (distinct
> (project (?ind ?boss ?g)
> (union
> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
> (filter (= ?boss "mathieu")
> (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))))))
>
> 2) Travere the tree to modify its internal structure. In terms of code, I can write:
>
> (A) Transform transform = new TransformRemoveOp(q,tp) ;
> (B) op = Transformer.transform(transform, op);
>
> where TransformRemoveOp implements Transform interface.
> It seems that there is no link between children and parent that can be used to figure out at which level the process is and modify the Tree structure, accordingly. Please correct me if I am wrong.
> In fact running it over the above example, I got the following:
>
> =========== DURING
> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 1
> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>
>
> [TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 2
> [TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))
>
>
> [TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty (bgp
> )
>
> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter (filter (= ?boss "mathieu")
> (bgp
> ))
>
> [TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name bgp
>
> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] left: (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
>
> [TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] right: (filter (exprlist (= ?boss "mathieu") true)
> (bgp
> ))
>
>
> [TransformRemoveOp::transform(OpProject opProject, Op subOp)] (project (?ind ?boss ?g)
> (union
> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
> (filter (exprlist (= ?boss "mathieu") true)
> (bgp
> ))))
>
>
> [TransformRemoveOp::transform(OpDistinct opDistinct, Op subOp)] (distinct
> (project (?ind ?boss ?g)
> (union
> (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
> (filter (exprlist (= ?boss "mathieu") true)
> (bgp
> )))))
>
>
> Moreover, implementing a first version of the OpFilter as reported below:
>
> @Override
> public Op transform(OpFilter opFilter, Op subOp) {
> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter " + opFilter.toString());
> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name " + subOp.getName());
> System.out.println("");
>
> if (isParent == false) {
> return opFilter;
> }
>
> //...get the variables of the triple pattern that we want to delete
> Set<Var> tpVars = new HashSet();
> Node subj = this.triple.getSubject();
> if (subj.isVariable()) {
> tpVars.add((Var) subj);
> }
> Node pred = this.triple.getPredicate();
> if (pred.isVariable()) {
> tpVars.add((Var) pred);
> }
> Node obj = this.triple.getObject();
> if (obj.isVariable()) {
> tpVars.add((Var) obj);
> }
> //...get the variables of the FILTER expression
> Op opNew = opFilter.copy(subOp);
> Set<Var> expVars = ((OpFilter) opNew).getExprs().getVarsMentioned();
>
> //...check whether the FILTER expression contains any of the triple pattern variable
> boolean isContained = false;
> for (Var var : expVars) {
> //..if it does then we have to delete the entire FILTER expression
> if (tpVars.contains(var)) {
> isContained = true;
> break;
> }
> }
> //... if the filter contains any variable of the triple that has been removed, then....
> if (isContained) {
> Op newOP;
> Expr e;
> if (subOp instanceof OpBGP) {
> if (((OpBGP) subOp).getPattern().getList().isEmpty()) {
> e = new NodeValueBoolean(true);
> newOP = OpFilter.filter(e, opFilter);//filter(e, );
> return newOP;
> } else {
> e = new NodeValueBoolean(false);
> newOP = OpFilter.filter(e, opFilter);//filter(e, );
> return newOP;
> }
> }
> }
> return opFilter;
> }
>
> It produces the following SPARQL query:
>
> SELECT DISTINCT ?ind ?boss ?g
> WHERE
> { { ?ind a ?z }
> UNION
> { # Empty BGP
>
> FILTER ( ?boss = "mathieu" )
> FILTER ( true )
> }
> }
>
> It seems quite challenging even transform the expression of "?boss = “mathieu” into “true” (as reported above) does not work as It should.
>
> If anyone could help me who is more experienced with this kind of task, I would be very very grateful.
> I would like to see something concrete in sense of line of code as I am using.
>
> Many Thanks,
> Best Regards,
> Carlo
> On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
>
> element has active parts
>
> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Dear Andy,
Thank you very much one more time.
Please, some comments follow in line.
On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
On 30/01/16 15:52, Carlo.Allocca wrote:
Hello Lorenz,
Thank you for your help.
It was clear to me that I have to remove from the parent expression and such is that using a patter-based approach
make it a bit difficult. I tried three of them and I got to the same results.
You need to process the parent, not just the ElementFilter.
How can I process the parent?
My understanding is:
1. Building the Abstract Query Tree: Op op = Algebra.compile(q);
For example, given the query
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://www.semanticweb.org/dataset1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind rdf:type ?z }
UNION
{ ?boss ex:isBossOf ?ind
FILTER ( ?boss = "mathieu" )
}
}
I obtain
(distinct
(project (?ind ?boss ?g)
(union
(bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
(filter (= ?boss "mathieu")
(bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))))))
2) Travere the tree to modify its internal structure. In terms of code, I can write:
(A) Transform transform = new TransformRemoveOp(q,tp) ;
(B) op = Transformer.transform(transform, op);
where TransformRemoveOp implements Transform interface.
It seems that there is no link between children and parent that can be used to figure out at which level the process is and modify the Tree structure, accordingly. Please correct me if I am wrong.
In fact running it over the above example, I got the following:
=========== DURING
[TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 1
[TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
[TransformRemoveOp::transform(OpBGP opBGP)] opBGPCounter 2
[TransformRemoveOp::transform(OpBGP opBGP)] (bgp (triple ?boss <http://www.semanticweb.org/dataset1/isBossOf> ?ind))
[TransformRemoveOp::transform(OpBGP opBGP)] opBGP is empty (bgp
)
[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter (filter (= ?boss "mathieu")
(bgp
))
[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name bgp
[TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] left: (bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
[TransformRemoveOp::transform(OpUnion opUnion, Op left, Op right)] right: (filter (exprlist (= ?boss "mathieu") true)
(bgp
))
[TransformRemoveOp::transform(OpProject opProject, Op subOp)] (project (?ind ?boss ?g)
(union
(bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
(filter (exprlist (= ?boss "mathieu") true)
(bgp
))))
[TransformRemoveOp::transform(OpDistinct opDistinct, Op subOp)] (distinct
(project (?ind ?boss ?g)
(union
(bgp (triple ?ind <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?z))
(filter (exprlist (= ?boss "mathieu") true)
(bgp
)))))
Moreover, implementing a first version of the OpFilter as reported below:
@Override
public Op transform(OpFilter opFilter, Op subOp) {
System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] opFilter " + opFilter.toString());
System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] subOp Name " + subOp.getName());
System.out.println("");
if (isParent == false) {
return opFilter;
}
//...get the variables of the triple pattern that we want to delete
Set<Var> tpVars = new HashSet();
Node subj = this.triple.getSubject();
if (subj.isVariable()) {
tpVars.add((Var) subj);
}
Node pred = this.triple.getPredicate();
if (pred.isVariable()) {
tpVars.add((Var) pred);
}
Node obj = this.triple.getObject();
if (obj.isVariable()) {
tpVars.add((Var) obj);
}
//...get the variables of the FILTER expression
Op opNew = opFilter.copy(subOp);
Set<Var> expVars = ((OpFilter) opNew).getExprs().getVarsMentioned();
//...check whether the FILTER expression contains any of the triple pattern variable
boolean isContained = false;
for (Var var : expVars) {
//..if it does then we have to delete the entire FILTER expression
if (tpVars.contains(var)) {
isContained = true;
break;
}
}
//... if the filter contains any variable of the triple that has been removed, then....
if (isContained) {
Op newOP;
Expr e;
if (subOp instanceof OpBGP) {
if (((OpBGP) subOp).getPattern().getList().isEmpty()) {
e = new NodeValueBoolean(true);
newOP = OpFilter.filter(e, opFilter);//filter(e, );
return newOP;
} else {
e = new NodeValueBoolean(false);
newOP = OpFilter.filter(e, opFilter);//filter(e, );
return newOP;
}
}
}
return opFilter;
}
It produces the following SPARQL query:
SELECT DISTINCT ?ind ?boss ?g
WHERE
{ { ?ind a ?z }
UNION
{ # Empty BGP
FILTER ( ?boss = "mathieu" )
FILTER ( true )
}
}
It seems quite challenging even transform the expression of "?boss = “mathieu” into “true” (as reported above) does not work as It should.
If anyone could help me who is more experienced with this kind of task, I would be very very grateful.
I would like to see something concrete in sense of line of code as I am using.
Many Thanks,
Best Regards,
Carlo
On 30 Jan 2016, at 17:53, Andy Seaborne <an...@apache.org>> wrote:
element has active parts
-- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
Re: How to remove consistently a triple pattern given a SPARQL query?
Posted by Andy Seaborne <an...@apache.org>.
On 30/01/16 15:52, Carlo.Allocca wrote:
> Hello Lorenz,
>
> Thank you for your help.
>
> It was clear to me that I have to remove from the parent expression and such is that using a patter-based approach
> make it a bit difficult. I tried three of them and I got to the same results.
You need to process the parent, not just the ElementFilter.
You also need to handle the case of an ElementGroup becoming empty (you
will get one solution, one column, no rows; not zero-rows).
The easy route is to leave the filter in place but set it to be a no-op
like OpFilter(true,...) if the element has active parts still, and
OpFilter(false, ...) if the subOp is empty. The execution difference is
minimal.
Andy
>
> I am reading and learning about more Jena packages to figure out how to write the appropriate lines of code.
> In case you have any advice, it would be very appreciated.
>
> Many Thanks,
> Best Regards,
> Carlo
>
>
> ________________________________________
> From: Lorenz Bühmann [buehmann@informatik.uni-leipzig.de]
> Sent: Saturday, January 30, 2016 1:51 PM
> To: users@jena.apache.org
> Subject: Re: How to remove consistently a triple pattern given a SPARQL query?
>
> Hello Carlo,
>
> you have to remove the whole filter from it's parent expression, which
> makes it a little bit more difficult in a visitor pattern-based
> implementation. But should be rather simple, just some lines of code.
>
> Lorenz
>
>> Dear Andy and all,
>>
>> Thank yo very much for your help to accomplish this task.
>> I am using the package org.apache.jena.sparql.syntax as suggested.
>>
>> The way I am doing it is the following:
>>
>>
>>
>> ===== MAIN CLASS
>> // This is the main method to implement the remove of a triple from a SPARQL query
>> private static Query RemoveOpImplementation(Query q, Triple tp) {
>>
>>
>>
>> Op op = Algebra.compile(q);
>> Transform transform = new TransformRemoveOp(q,tp) ;
>> op = Transformer.transform(transform, op) ;
>> Query queryWithoutTriplePattern = OpAsQuery.asQuery(op) ;
>>
>> }
>>
>>
>> ===== TransformRemoveOp
>> // the implement the transform
>> public class TransformRemoveOp implements Transform {
>>
>> }
>>
>> Again, removing the triple is quite straightforward
>>
>>
>> @Override
>> public Op transform(OpBGP opBGP) {
>> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] " + opBGP.toString());
>> System.out.println("");
>> Op opNew = opBGP.copy();
>> BasicPattern newBP = ((OpBGP) opNew).getPattern();
>> List<Triple> tripleList = newBP.getList();
>>
>> Iterator<Triple> itr = tripleList.iterator();
>> while (itr.hasNext()) {
>> Triple tp = itr.next();
>> if (tp.matches(this.triple)) {
>> itr.remove();
>> }
>> }
>> return opNew;
>> }
>>
>>
>> but not the Filter
>>
>>
>>
>>
>> @Override
>> public Op transform(OpFilter opFilter, Op subOp) {
>>
>> //...get the variables of the triple pattern that we want to delete
>> Set<Var> tpVars = new HashSet();
>> Node subj = this.triple.getSubject();
>> if (subj.isVariable()) {
>> tpVars.add((Var) subj);
>> }
>> Node pred = this.triple.getPredicate();
>> if (pred.isVariable()) {
>> tpVars.add((Var) pred);
>> }
>> Node obj = this.triple.getObject();
>> if (obj.isVariable()) {
>> tpVars.add((Var) obj);
>> }
>>
>> //...get the variables of the FILTER expression
>> Op opNew=opFilter.copy(subOp);
>> Set<Var> expVars = ((OpFilter)opNew).getExprs().getVarsMentioned();
>>
>>
>>
>> //...check whether the FILTER expression contains any of the triple pattern variable
>> for (Var var : expVars) {
>> //..if it does then we have to delete the entire FILTER expression
>> if (tpVars.contains(var)) {
>> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] FILTER TO BE REMOVED!!!HOW? ");
>> System.out.println("");
>> }
>> }
>> return opFilter;
>> }
>>
>> Sorry for posting again and again the same question.
>> What am I missing or not understanding?
>> How should I use the abstract syntax tree to do it?
>>
>> I am looking at the code of the example reported in Jena, but still I am strangling to find it out.
>> Please, any example code that I could have look at?
>>
>> Many Thanks in advance for your help and support.
>> Best Regards,
>> Carlo
>> On 29 Jan 2016, at 14:16, Andy Seaborne <an...@apache.org>> wrote:
>>
>> On 29/01/16 12:57, Carlo.Allocca wrote:
>> Dear Andy and All,
>>
>> I tried to use as many suggested info as I could. As result, I obtained the following:
>>
>> I am implementing a public class RemoveOpTransform implements ElementTransform. And, again It is quite straightforward to remove the triple pattern from the ElementPathBlock
>>
>> @Override
>> public Element transform(ElementPathBlock eltPB) {
>>
>> The idea of the transform design is to not change the inoput but to create a new copy if you change it. If you don't change it you can return the input.
>>
>>
>> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] " + eltPB.toString());
>> Iterator<TriplePath> l = eltPB.patternElts();
>> while (l.hasNext()) {
>> TriplePath tp = l.next();
>> if (tp.asTriple().matches(this.triple)) {
>> l.remove();
>> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] TRIPLE MAP JUST REMOVED!!! ");
>> System.out.println("");
>> return this.transform(eltPB);//eltPB;
>> }
>> }
>> return eltPB;
>> }
>>
>> But I could not figure out how to remove the associated FILTER when transform(ElementFilter arg0, Expr arg1) as below
>>
>> To remove a filter altogether you need to delete the ElementFilter object from the AST (abstract syntax tree). You can't do that inside the transform/ElementFilter.
>>
>> It means looking in the element containing the ElementFilter which will be in a ElementGroup of some kind, probably as part of an ElementUnion.
>>
>> An alternative is to replace the filter expression with a no-op like
>>
>> FILTER(true)
>>
>> and live with that.
>>
>> Andy
>>
>>
>> @Override
>> public Element transform(ElementFilter arg0, Expr arg1) {
>>
>> //...get the variables of the triple pattern that we want to delete
>> Set<Var> tpVars = new HashSet();
>> Node subj = this.triple.getSubject();
>> if (subj.isVariable()) {
>> tpVars.add((Var) subj);
>> }
>> Node pred = this.triple.getPredicate();
>> if (pred.isVariable()) {
>> tpVars.add((Var) pred);
>> }
>> Node obj = this.triple.getObject();
>> if (obj.isVariable()) {
>> tpVars.add((Var) obj);
>> }
>>
>> //...get the variables of the FILTER expression
>> Set<Var> expVars = arg1.getVarsMentioned();
>>
>> //...check whether the FILTER expression contains any of the triple pattern variable
>> for (Var var : expVars) {
>> //..if it does then we have to delete the entire FILTER expression
>> if (tpVars.contains(var)) {
>> System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter arg0)] FILTER TO BE REMOVED!!!HOW? ");
>> System.out.println("");
>> }
>> }
>>
>> return arg0;
>> }
>>
>> It appears to me that I am at the same point of the previous approach.
>> What am I doing wrong or missing? Or what I should ready to figure it out?
>>
>> Thank you very much for your kind help and support.
>>
>> Best Regards,
>> Carlo
>>
>>
>>
>>
>> On 29 Jan 2016, at 10:32, Andy Seaborne <an...@apache.org>> wrote:
>>
>> You'll still have to clean up structures. SPIN for this is encoding the query in RDF but the rewriting of that structure needs the same (in the abstract) processing. You may be able to do it with a series of SPARQL Updates (that's speculation).
>>
>> Andy
>>
>> On 29/01/16 00:26, Carlo.Allocca wrote:
>> Dear Martynas,
>>
>>
>> Thank you very much for your help.
>> At the moment, I am trying what Andy suggested.
>> I hope to make it. Otherwise, I will look at SPIN API.
>>
>> Many Thanks,
>> Best Regards,
>> Carlo
>>
>>
>> On 28 Jan 2016, at 23:48, Martynas Jusevičius <ma...@graphity.org>> wrote:
>>
>> You could do it using SPIN API as well: http://spinrdf.org/sp.html
>>
>> On Thu, Jan 28, 2016 at 7:39 PM, Carlo.Allocca <ca...@open.ac.uk>> wrote:
>> Dear Andy,
>>
>> Thank you very much for your promtly reply.
>>
>> I need a little bit of exploring and thinking to apply what you suggested.
>> Indeed, I will look at each single info you pointed out.
>>
>> I will keep this thread updated.
>>
>> Many Thanks,
>> Best Regards,
>> Carlo
>>
>> On 28 Jan 2016, at 18:29, Andy Seaborne <an...@apache.org>> wrote:
>>
>> The approach I would take is to do this is multiple passes:
>>
>> 1/ remove from ElementPathBlock
>>
>> 2/ Look for elements that are now "empty"
>> e.g ElementFilter with empty
>> but also as there one arm of a UNION.
>>
>> (2) is only one pass as the rewrite is done bottom up.
>>
>>
>> I would do this as a transformation rather than modifying the syntax tree in place.
>>
>> org.apache.jena.sparql.syntax.syntaxtransform
>>
>>
>> See also
>> ElementTransformCleanGroupsOfOne
>>
>> which might be helpful to understand - its doing something different though.
>>
>> It might be easier to work on the algebra, it's more regular. Then use OpAsQuery to turn algebnra into a Query.
>>
>> I could not figure out how to remove the associated FILTER
>> when visit(ElementFilter el) as below.
>>
>> because you need to alter the ElementUnion which holds the ElementFilter.
>>
>> {...} UNION {} will include a blank row for the {} on the right hand side.
>>
>> Andy
>>
>>
>> On 28/01/16 13:14, Carlo.Allocca wrote:
>> Dear All,
>>
>> I am using Jena for my project and I would like to submit the following question: How to remove consistently a triple pattern given a SPARQL query?
>>
>> EXAMPLE:
>>
>> For example, considering the query “qString1” and the tp=“?boss ex:isBossOf ?ind .”
>> I need to remove tp from qString1, obtaining qString1. For “Consistently” I mean that the clause FILTER gets affected (as it contains var that appears in the triple pattern too), therefore it needs to be deleted too.
>>
>> String qString1 =
>> " SELECT DISTINCT ?ind ?boss ?g where "
>> + "{ "
>> + " ?ind rdf:type ex:AssociatedResearcher ."
>> + " {?ind rdf:type ?z. } UNION "
>> + " {?boss ex:isBossOf ?ind . Filter(?boss=\”rossi\”)} "
>> + "}";
>>
>>
>> String qString2 =
>> " SELECT DISTINCT ?ind ?boss ?g “
>> + “WHERE "
>> + "{ "
>> + " ?ind rdf:type ex:AssociatedResearcher ."
>> + " {?ind rdf:type ?z. } UNION "
>> + " {} "
>> + "}";
>>
>> The solution that I am trying to implement is based on a visitor “SQRemoveTripleVisitor extends ElementVisitorBase”.
>> It is quite straightforward to remove the triple pattern when visit(ElementPathBlock el)
>>
>> @Override
>> public void visit(ElementPathBlock el) {
>> if (el == null) {
>> throw new IllegalStateException("[SQRemoveTripleVisitor::visit(ElementPathBlock el)] The ElementPathBlock is null!!");
>> }
>>
>> ListIterator<TriplePath> it = el.getPattern().iterator();
>> while (it.hasNext()) {
>> final TriplePath tp1 = it.next();
>>
>> if (this.tp != null) {
>> if (this.tp.matches(tp1.asTriple())) {
>> it.remove();
>> }
>> }
>> }
>>
>> }
>>
>> I could not figure out how to remove the associated FILTER when visit(ElementFilter el) as below.
>>
>>
>> @Override
>> public void visit(ElementFilter el) {
>>
>> //...get the variables of the FILTER expression
>> Expr filterExp = el.getExpr();//.getVarsMentioned().contains(el);
>> Set<Var> expVars = filterExp.getVarsMentioned();
>>
>> //...get the variables of the triple pattern that we want to delete
>> Set<Var> tpVars = new HashSet();
>> Node subj = this.tp.getSubject();
>> if (subj.isVariable()) {
>> tpVars.add((Var) subj);
>> }
>> Node pred = this.tp.getPredicate();
>> if (pred.isVariable()) {
>> tpVars.add((Var) pred);
>> }
>> Node obj = this.tp.getObject();
>> if (obj.isVariable()) {
>> tpVars.add((Var) obj);
>> }
>>
>> //...check whether the FILTER expression contains any of the triple pattern’s variable
>> for(Var var:expVars){
>> //…if it does then we have to delete the entire FILTER expression
>> if(tpVars.contains(var)){
>> System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter el)] I NEED TO REMOVE THE FILTER!!!!!! ");
>>
>> }
>> }
>>
>> }
>>
>> Please, may I ask for any help or idea on how to remove the filter?
>>
>>
>> Many Thanks in advance.
>>
>> Best Regards,
>> Carlo
>>
>>
>> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>>
> --
> Lorenz Bühmann
> AKSW group, University of Leipzig
> Group: http://aksw.org - semantic web research center
>
RE: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Hello Lorenz,
Thank you for your help.
It was clear to me that I have to remove from the parent expression and such is that using a patter-based approach
make it a bit difficult. I tried three of them and I got to the same results.
I am reading and learning about more Jena packages to figure out how to write the appropriate lines of code.
In case you have any advice, it would be very appreciated.
Many Thanks,
Best Regards,
Carlo
________________________________________
From: Lorenz Bühmann [buehmann@informatik.uni-leipzig.de]
Sent: Saturday, January 30, 2016 1:51 PM
To: users@jena.apache.org
Subject: Re: How to remove consistently a triple pattern given a SPARQL query?
Hello Carlo,
you have to remove the whole filter from it's parent expression, which
makes it a little bit more difficult in a visitor pattern-based
implementation. But should be rather simple, just some lines of code.
Lorenz
> Dear Andy and all,
>
> Thank yo very much for your help to accomplish this task.
> I am using the package org.apache.jena.sparql.syntax as suggested.
>
> The way I am doing it is the following:
>
>
>
> ===== MAIN CLASS
> // This is the main method to implement the remove of a triple from a SPARQL query
> private static Query RemoveOpImplementation(Query q, Triple tp) {
>
>
>
> Op op = Algebra.compile(q);
> Transform transform = new TransformRemoveOp(q,tp) ;
> op = Transformer.transform(transform, op) ;
> Query queryWithoutTriplePattern = OpAsQuery.asQuery(op) ;
>
> }
>
>
> ===== TransformRemoveOp
> // the implement the transform
> public class TransformRemoveOp implements Transform {
>
> }
>
> Again, removing the triple is quite straightforward
>
>
> @Override
> public Op transform(OpBGP opBGP) {
> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] " + opBGP.toString());
> System.out.println("");
> Op opNew = opBGP.copy();
> BasicPattern newBP = ((OpBGP) opNew).getPattern();
> List<Triple> tripleList = newBP.getList();
>
> Iterator<Triple> itr = tripleList.iterator();
> while (itr.hasNext()) {
> Triple tp = itr.next();
> if (tp.matches(this.triple)) {
> itr.remove();
> }
> }
> return opNew;
> }
>
>
> but not the Filter
>
>
>
>
> @Override
> public Op transform(OpFilter opFilter, Op subOp) {
>
> //...get the variables of the triple pattern that we want to delete
> Set<Var> tpVars = new HashSet();
> Node subj = this.triple.getSubject();
> if (subj.isVariable()) {
> tpVars.add((Var) subj);
> }
> Node pred = this.triple.getPredicate();
> if (pred.isVariable()) {
> tpVars.add((Var) pred);
> }
> Node obj = this.triple.getObject();
> if (obj.isVariable()) {
> tpVars.add((Var) obj);
> }
>
> //...get the variables of the FILTER expression
> Op opNew=opFilter.copy(subOp);
> Set<Var> expVars = ((OpFilter)opNew).getExprs().getVarsMentioned();
>
>
>
> //...check whether the FILTER expression contains any of the triple pattern variable
> for (Var var : expVars) {
> //..if it does then we have to delete the entire FILTER expression
> if (tpVars.contains(var)) {
> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] FILTER TO BE REMOVED!!!HOW? ");
> System.out.println("");
> }
> }
> return opFilter;
> }
>
> Sorry for posting again and again the same question.
> What am I missing or not understanding?
> How should I use the abstract syntax tree to do it?
>
> I am looking at the code of the example reported in Jena, but still I am strangling to find it out.
> Please, any example code that I could have look at?
>
> Many Thanks in advance for your help and support.
> Best Regards,
> Carlo
> On 29 Jan 2016, at 14:16, Andy Seaborne <an...@apache.org>> wrote:
>
> On 29/01/16 12:57, Carlo.Allocca wrote:
> Dear Andy and All,
>
> I tried to use as many suggested info as I could. As result, I obtained the following:
>
> I am implementing a public class RemoveOpTransform implements ElementTransform. And, again It is quite straightforward to remove the triple pattern from the ElementPathBlock
>
> @Override
> public Element transform(ElementPathBlock eltPB) {
>
> The idea of the transform design is to not change the inoput but to create a new copy if you change it. If you don't change it you can return the input.
>
>
> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] " + eltPB.toString());
> Iterator<TriplePath> l = eltPB.patternElts();
> while (l.hasNext()) {
> TriplePath tp = l.next();
> if (tp.asTriple().matches(this.triple)) {
> l.remove();
> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] TRIPLE MAP JUST REMOVED!!! ");
> System.out.println("");
> return this.transform(eltPB);//eltPB;
> }
> }
> return eltPB;
> }
>
> But I could not figure out how to remove the associated FILTER when transform(ElementFilter arg0, Expr arg1) as below
>
> To remove a filter altogether you need to delete the ElementFilter object from the AST (abstract syntax tree). You can't do that inside the transform/ElementFilter.
>
> It means looking in the element containing the ElementFilter which will be in a ElementGroup of some kind, probably as part of an ElementUnion.
>
> An alternative is to replace the filter expression with a no-op like
>
> FILTER(true)
>
> and live with that.
>
> Andy
>
>
> @Override
> public Element transform(ElementFilter arg0, Expr arg1) {
>
> //...get the variables of the triple pattern that we want to delete
> Set<Var> tpVars = new HashSet();
> Node subj = this.triple.getSubject();
> if (subj.isVariable()) {
> tpVars.add((Var) subj);
> }
> Node pred = this.triple.getPredicate();
> if (pred.isVariable()) {
> tpVars.add((Var) pred);
> }
> Node obj = this.triple.getObject();
> if (obj.isVariable()) {
> tpVars.add((Var) obj);
> }
>
> //...get the variables of the FILTER expression
> Set<Var> expVars = arg1.getVarsMentioned();
>
> //...check whether the FILTER expression contains any of the triple pattern variable
> for (Var var : expVars) {
> //..if it does then we have to delete the entire FILTER expression
> if (tpVars.contains(var)) {
> System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter arg0)] FILTER TO BE REMOVED!!!HOW? ");
> System.out.println("");
> }
> }
>
> return arg0;
> }
>
> It appears to me that I am at the same point of the previous approach.
> What am I doing wrong or missing? Or what I should ready to figure it out?
>
> Thank you very much for your kind help and support.
>
> Best Regards,
> Carlo
>
>
>
>
> On 29 Jan 2016, at 10:32, Andy Seaborne <an...@apache.org>> wrote:
>
> You'll still have to clean up structures. SPIN for this is encoding the query in RDF but the rewriting of that structure needs the same (in the abstract) processing. You may be able to do it with a series of SPARQL Updates (that's speculation).
>
> Andy
>
> On 29/01/16 00:26, Carlo.Allocca wrote:
> Dear Martynas,
>
>
> Thank you very much for your help.
> At the moment, I am trying what Andy suggested.
> I hope to make it. Otherwise, I will look at SPIN API.
>
> Many Thanks,
> Best Regards,
> Carlo
>
>
> On 28 Jan 2016, at 23:48, Martynas Jusevičius <ma...@graphity.org>> wrote:
>
> You could do it using SPIN API as well: http://spinrdf.org/sp.html
>
> On Thu, Jan 28, 2016 at 7:39 PM, Carlo.Allocca <ca...@open.ac.uk>> wrote:
> Dear Andy,
>
> Thank you very much for your promtly reply.
>
> I need a little bit of exploring and thinking to apply what you suggested.
> Indeed, I will look at each single info you pointed out.
>
> I will keep this thread updated.
>
> Many Thanks,
> Best Regards,
> Carlo
>
> On 28 Jan 2016, at 18:29, Andy Seaborne <an...@apache.org>> wrote:
>
> The approach I would take is to do this is multiple passes:
>
> 1/ remove from ElementPathBlock
>
> 2/ Look for elements that are now "empty"
> e.g ElementFilter with empty
> but also as there one arm of a UNION.
>
> (2) is only one pass as the rewrite is done bottom up.
>
>
> I would do this as a transformation rather than modifying the syntax tree in place.
>
> org.apache.jena.sparql.syntax.syntaxtransform
>
>
> See also
> ElementTransformCleanGroupsOfOne
>
> which might be helpful to understand - its doing something different though.
>
> It might be easier to work on the algebra, it's more regular. Then use OpAsQuery to turn algebnra into a Query.
>
> I could not figure out how to remove the associated FILTER
> when visit(ElementFilter el) as below.
>
> because you need to alter the ElementUnion which holds the ElementFilter.
>
> {...} UNION {} will include a blank row for the {} on the right hand side.
>
> Andy
>
>
> On 28/01/16 13:14, Carlo.Allocca wrote:
> Dear All,
>
> I am using Jena for my project and I would like to submit the following question: How to remove consistently a triple pattern given a SPARQL query?
>
> EXAMPLE:
>
> For example, considering the query “qString1” and the tp=“?boss ex:isBossOf ?ind .”
> I need to remove tp from qString1, obtaining qString1. For “Consistently” I mean that the clause FILTER gets affected (as it contains var that appears in the triple pattern too), therefore it needs to be deleted too.
>
> String qString1 =
> " SELECT DISTINCT ?ind ?boss ?g where "
> + "{ "
> + " ?ind rdf:type ex:AssociatedResearcher ."
> + " {?ind rdf:type ?z. } UNION "
> + " {?boss ex:isBossOf ?ind . Filter(?boss=\”rossi\”)} "
> + "}";
>
>
> String qString2 =
> " SELECT DISTINCT ?ind ?boss ?g “
> + “WHERE "
> + "{ "
> + " ?ind rdf:type ex:AssociatedResearcher ."
> + " {?ind rdf:type ?z. } UNION "
> + " {} "
> + "}";
>
> The solution that I am trying to implement is based on a visitor “SQRemoveTripleVisitor extends ElementVisitorBase”.
> It is quite straightforward to remove the triple pattern when visit(ElementPathBlock el)
>
> @Override
> public void visit(ElementPathBlock el) {
> if (el == null) {
> throw new IllegalStateException("[SQRemoveTripleVisitor::visit(ElementPathBlock el)] The ElementPathBlock is null!!");
> }
>
> ListIterator<TriplePath> it = el.getPattern().iterator();
> while (it.hasNext()) {
> final TriplePath tp1 = it.next();
>
> if (this.tp != null) {
> if (this.tp.matches(tp1.asTriple())) {
> it.remove();
> }
> }
> }
>
> }
>
> I could not figure out how to remove the associated FILTER when visit(ElementFilter el) as below.
>
>
> @Override
> public void visit(ElementFilter el) {
>
> //...get the variables of the FILTER expression
> Expr filterExp = el.getExpr();//.getVarsMentioned().contains(el);
> Set<Var> expVars = filterExp.getVarsMentioned();
>
> //...get the variables of the triple pattern that we want to delete
> Set<Var> tpVars = new HashSet();
> Node subj = this.tp.getSubject();
> if (subj.isVariable()) {
> tpVars.add((Var) subj);
> }
> Node pred = this.tp.getPredicate();
> if (pred.isVariable()) {
> tpVars.add((Var) pred);
> }
> Node obj = this.tp.getObject();
> if (obj.isVariable()) {
> tpVars.add((Var) obj);
> }
>
> //...check whether the FILTER expression contains any of the triple pattern’s variable
> for(Var var:expVars){
> //…if it does then we have to delete the entire FILTER expression
> if(tpVars.contains(var)){
> System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter el)] I NEED TO REMOVE THE FILTER!!!!!! ");
>
> }
> }
>
> }
>
> Please, may I ask for any help or idea on how to remove the filter?
>
>
> Many Thanks in advance.
>
> Best Regards,
> Carlo
>
>
> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>
--
Lorenz Bühmann
AKSW group, University of Leipzig
Group: http://aksw.org - semantic web research center
Re: How to remove consistently a triple pattern given a SPARQL query?
Posted by Lorenz Bühmann <bu...@informatik.uni-leipzig.de>.
Hello Carlo,
you have to remove the whole filter from it's parent expression, which
makes it a little bit more difficult in a visitor pattern-based
implementation. But should be rather simple, just some lines of code.
Lorenz
> Dear Andy and all,
>
> Thank yo very much for your help to accomplish this task.
> I am using the package org.apache.jena.sparql.syntax as suggested.
>
> The way I am doing it is the following:
>
>
>
> ===== MAIN CLASS
> // This is the main method to implement the remove of a triple from a SPARQL query
> private static Query RemoveOpImplementation(Query q, Triple tp) {
>
>
>
> Op op = Algebra.compile(q);
> Transform transform = new TransformRemoveOp(q,tp) ;
> op = Transformer.transform(transform, op) ;
> Query queryWithoutTriplePattern = OpAsQuery.asQuery(op) ;
>
> }
>
>
> ===== TransformRemoveOp
> // the implement the transform
> public class TransformRemoveOp implements Transform {
>
> }
>
> Again, removing the triple is quite straightforward
>
>
> @Override
> public Op transform(OpBGP opBGP) {
> System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] " + opBGP.toString());
> System.out.println("");
> Op opNew = opBGP.copy();
> BasicPattern newBP = ((OpBGP) opNew).getPattern();
> List<Triple> tripleList = newBP.getList();
>
> Iterator<Triple> itr = tripleList.iterator();
> while (itr.hasNext()) {
> Triple tp = itr.next();
> if (tp.matches(this.triple)) {
> itr.remove();
> }
> }
> return opNew;
> }
>
>
> but not the Filter
>
>
>
>
> @Override
> public Op transform(OpFilter opFilter, Op subOp) {
>
> //...get the variables of the triple pattern that we want to delete
> Set<Var> tpVars = new HashSet();
> Node subj = this.triple.getSubject();
> if (subj.isVariable()) {
> tpVars.add((Var) subj);
> }
> Node pred = this.triple.getPredicate();
> if (pred.isVariable()) {
> tpVars.add((Var) pred);
> }
> Node obj = this.triple.getObject();
> if (obj.isVariable()) {
> tpVars.add((Var) obj);
> }
>
> //...get the variables of the FILTER expression
> Op opNew=opFilter.copy(subOp);
> Set<Var> expVars = ((OpFilter)opNew).getExprs().getVarsMentioned();
>
>
>
> //...check whether the FILTER expression contains any of the triple pattern variable
> for (Var var : expVars) {
> //..if it does then we have to delete the entire FILTER expression
> if (tpVars.contains(var)) {
> System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] FILTER TO BE REMOVED!!!HOW? ");
> System.out.println("");
> }
> }
> return opFilter;
> }
>
> Sorry for posting again and again the same question.
> What am I missing or not understanding?
> How should I use the abstract syntax tree to do it?
>
> I am looking at the code of the example reported in Jena, but still I am strangling to find it out.
> Please, any example code that I could have look at?
>
> Many Thanks in advance for your help and support.
> Best Regards,
> Carlo
> On 29 Jan 2016, at 14:16, Andy Seaborne <an...@apache.org>> wrote:
>
> On 29/01/16 12:57, Carlo.Allocca wrote:
> Dear Andy and All,
>
> I tried to use as many suggested info as I could. As result, I obtained the following:
>
> I am implementing a public class RemoveOpTransform implements ElementTransform. And, again It is quite straightforward to remove the triple pattern from the ElementPathBlock
>
> @Override
> public Element transform(ElementPathBlock eltPB) {
>
> The idea of the transform design is to not change the inoput but to create a new copy if you change it. If you don't change it you can return the input.
>
>
> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] " + eltPB.toString());
> Iterator<TriplePath> l = eltPB.patternElts();
> while (l.hasNext()) {
> TriplePath tp = l.next();
> if (tp.asTriple().matches(this.triple)) {
> l.remove();
> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] TRIPLE MAP JUST REMOVED!!! ");
> System.out.println("");
> return this.transform(eltPB);//eltPB;
> }
> }
> return eltPB;
> }
>
> But I could not figure out how to remove the associated FILTER when transform(ElementFilter arg0, Expr arg1) as below
>
> To remove a filter altogether you need to delete the ElementFilter object from the AST (abstract syntax tree). You can't do that inside the transform/ElementFilter.
>
> It means looking in the element containing the ElementFilter which will be in a ElementGroup of some kind, probably as part of an ElementUnion.
>
> An alternative is to replace the filter expression with a no-op like
>
> FILTER(true)
>
> and live with that.
>
> Andy
>
>
> @Override
> public Element transform(ElementFilter arg0, Expr arg1) {
>
> //...get the variables of the triple pattern that we want to delete
> Set<Var> tpVars = new HashSet();
> Node subj = this.triple.getSubject();
> if (subj.isVariable()) {
> tpVars.add((Var) subj);
> }
> Node pred = this.triple.getPredicate();
> if (pred.isVariable()) {
> tpVars.add((Var) pred);
> }
> Node obj = this.triple.getObject();
> if (obj.isVariable()) {
> tpVars.add((Var) obj);
> }
>
> //...get the variables of the FILTER expression
> Set<Var> expVars = arg1.getVarsMentioned();
>
> //...check whether the FILTER expression contains any of the triple pattern variable
> for (Var var : expVars) {
> //..if it does then we have to delete the entire FILTER expression
> if (tpVars.contains(var)) {
> System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter arg0)] FILTER TO BE REMOVED!!!HOW? ");
> System.out.println("");
> }
> }
>
> return arg0;
> }
>
> It appears to me that I am at the same point of the previous approach.
> What am I doing wrong or missing? Or what I should ready to figure it out?
>
> Thank you very much for your kind help and support.
>
> Best Regards,
> Carlo
>
>
>
>
> On 29 Jan 2016, at 10:32, Andy Seaborne <an...@apache.org>> wrote:
>
> You'll still have to clean up structures. SPIN for this is encoding the query in RDF but the rewriting of that structure needs the same (in the abstract) processing. You may be able to do it with a series of SPARQL Updates (that's speculation).
>
> Andy
>
> On 29/01/16 00:26, Carlo.Allocca wrote:
> Dear Martynas,
>
>
> Thank you very much for your help.
> At the moment, I am trying what Andy suggested.
> I hope to make it. Otherwise, I will look at SPIN API.
>
> Many Thanks,
> Best Regards,
> Carlo
>
>
> On 28 Jan 2016, at 23:48, Martynas Jusevičius <ma...@graphity.org>> wrote:
>
> You could do it using SPIN API as well: http://spinrdf.org/sp.html
>
> On Thu, Jan 28, 2016 at 7:39 PM, Carlo.Allocca <ca...@open.ac.uk>> wrote:
> Dear Andy,
>
> Thank you very much for your promtly reply.
>
> I need a little bit of exploring and thinking to apply what you suggested.
> Indeed, I will look at each single info you pointed out.
>
> I will keep this thread updated.
>
> Many Thanks,
> Best Regards,
> Carlo
>
> On 28 Jan 2016, at 18:29, Andy Seaborne <an...@apache.org>> wrote:
>
> The approach I would take is to do this is multiple passes:
>
> 1/ remove from ElementPathBlock
>
> 2/ Look for elements that are now "empty"
> e.g ElementFilter with empty
> but also as there one arm of a UNION.
>
> (2) is only one pass as the rewrite is done bottom up.
>
>
> I would do this as a transformation rather than modifying the syntax tree in place.
>
> org.apache.jena.sparql.syntax.syntaxtransform
>
>
> See also
> ElementTransformCleanGroupsOfOne
>
> which might be helpful to understand - its doing something different though.
>
> It might be easier to work on the algebra, it's more regular. Then use OpAsQuery to turn algebnra into a Query.
>
> I could not figure out how to remove the associated FILTER
> when visit(ElementFilter el) as below.
>
> because you need to alter the ElementUnion which holds the ElementFilter.
>
> {...} UNION {} will include a blank row for the {} on the right hand side.
>
> Andy
>
>
> On 28/01/16 13:14, Carlo.Allocca wrote:
> Dear All,
>
> I am using Jena for my project and I would like to submit the following question: How to remove consistently a triple pattern given a SPARQL query?
>
> EXAMPLE:
>
> For example, considering the query “qString1” and the tp=“?boss ex:isBossOf ?ind .”
> I need to remove tp from qString1, obtaining qString1. For “Consistently” I mean that the clause FILTER gets affected (as it contains var that appears in the triple pattern too), therefore it needs to be deleted too.
>
> String qString1 =
> " SELECT DISTINCT ?ind ?boss ?g where "
> + "{ "
> + " ?ind rdf:type ex:AssociatedResearcher ."
> + " {?ind rdf:type ?z. } UNION "
> + " {?boss ex:isBossOf ?ind . Filter(?boss=\”rossi\”)} "
> + "}";
>
>
> String qString2 =
> " SELECT DISTINCT ?ind ?boss ?g “
> + “WHERE "
> + "{ "
> + " ?ind rdf:type ex:AssociatedResearcher ."
> + " {?ind rdf:type ?z. } UNION "
> + " {} "
> + "}";
>
> The solution that I am trying to implement is based on a visitor “SQRemoveTripleVisitor extends ElementVisitorBase”.
> It is quite straightforward to remove the triple pattern when visit(ElementPathBlock el)
>
> @Override
> public void visit(ElementPathBlock el) {
> if (el == null) {
> throw new IllegalStateException("[SQRemoveTripleVisitor::visit(ElementPathBlock el)] The ElementPathBlock is null!!");
> }
>
> ListIterator<TriplePath> it = el.getPattern().iterator();
> while (it.hasNext()) {
> final TriplePath tp1 = it.next();
>
> if (this.tp != null) {
> if (this.tp.matches(tp1.asTriple())) {
> it.remove();
> }
> }
> }
>
> }
>
> I could not figure out how to remove the associated FILTER when visit(ElementFilter el) as below.
>
>
> @Override
> public void visit(ElementFilter el) {
>
> //...get the variables of the FILTER expression
> Expr filterExp = el.getExpr();//.getVarsMentioned().contains(el);
> Set<Var> expVars = filterExp.getVarsMentioned();
>
> //...get the variables of the triple pattern that we want to delete
> Set<Var> tpVars = new HashSet();
> Node subj = this.tp.getSubject();
> if (subj.isVariable()) {
> tpVars.add((Var) subj);
> }
> Node pred = this.tp.getPredicate();
> if (pred.isVariable()) {
> tpVars.add((Var) pred);
> }
> Node obj = this.tp.getObject();
> if (obj.isVariable()) {
> tpVars.add((Var) obj);
> }
>
> //...check whether the FILTER expression contains any of the triple pattern’s variable
> for(Var var:expVars){
> //…if it does then we have to delete the entire FILTER expression
> if(tpVars.contains(var)){
> System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter el)] I NEED TO REMOVE THE FILTER!!!!!! ");
>
> }
> }
>
> }
>
> Please, may I ask for any help or idea on how to remove the filter?
>
>
> Many Thanks in advance.
>
> Best Regards,
> Carlo
>
>
> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>
--
Lorenz Bühmann
AKSW group, University of Leipzig
Group: http://aksw.org - semantic web research center
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Dear Andy and all,
Thank yo very much for your help to accomplish this task.
I am using the package org.apache.jena.sparql.syntax as suggested.
The way I am doing it is the following:
===== MAIN CLASS
// This is the main method to implement the remove of a triple from a SPARQL query
private static Query RemoveOpImplementation(Query q, Triple tp) {
Op op = Algebra.compile(q);
Transform transform = new TransformRemoveOp(q,tp) ;
op = Transformer.transform(transform, op) ;
Query queryWithoutTriplePattern = OpAsQuery.asQuery(op) ;
}
===== TransformRemoveOp
// the implement the transform
public class TransformRemoveOp implements Transform {
}
Again, removing the triple is quite straightforward
@Override
public Op transform(OpBGP opBGP) {
System.out.println("[TransformRemoveOp::transform(OpBGP opBGP)] " + opBGP.toString());
System.out.println("");
Op opNew = opBGP.copy();
BasicPattern newBP = ((OpBGP) opNew).getPattern();
List<Triple> tripleList = newBP.getList();
Iterator<Triple> itr = tripleList.iterator();
while (itr.hasNext()) {
Triple tp = itr.next();
if (tp.matches(this.triple)) {
itr.remove();
}
}
return opNew;
}
but not the Filter
@Override
public Op transform(OpFilter opFilter, Op subOp) {
//...get the variables of the triple pattern that we want to delete
Set<Var> tpVars = new HashSet();
Node subj = this.triple.getSubject();
if (subj.isVariable()) {
tpVars.add((Var) subj);
}
Node pred = this.triple.getPredicate();
if (pred.isVariable()) {
tpVars.add((Var) pred);
}
Node obj = this.triple.getObject();
if (obj.isVariable()) {
tpVars.add((Var) obj);
}
//...get the variables of the FILTER expression
Op opNew=opFilter.copy(subOp);
Set<Var> expVars = ((OpFilter)opNew).getExprs().getVarsMentioned();
//...check whether the FILTER expression contains any of the triple pattern variable
for (Var var : expVars) {
//..if it does then we have to delete the entire FILTER expression
if (tpVars.contains(var)) {
System.out.println("[TransformRemoveOp::transform(OpFilter opFilter, Op subOp)] FILTER TO BE REMOVED!!!HOW? ");
System.out.println("");
}
}
return opFilter;
}
Sorry for posting again and again the same question.
What am I missing or not understanding?
How should I use the abstract syntax tree to do it?
I am looking at the code of the example reported in Jena, but still I am strangling to find it out.
Please, any example code that I could have look at?
Many Thanks in advance for your help and support.
Best Regards,
Carlo
On 29 Jan 2016, at 14:16, Andy Seaborne <an...@apache.org>> wrote:
On 29/01/16 12:57, Carlo.Allocca wrote:
Dear Andy and All,
I tried to use as many suggested info as I could. As result, I obtained the following:
I am implementing a public class RemoveOpTransform implements ElementTransform. And, again It is quite straightforward to remove the triple pattern from the ElementPathBlock
@Override
public Element transform(ElementPathBlock eltPB) {
The idea of the transform design is to not change the inoput but to create a new copy if you change it. If you don't change it you can return the input.
System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] " + eltPB.toString());
Iterator<TriplePath> l = eltPB.patternElts();
while (l.hasNext()) {
TriplePath tp = l.next();
if (tp.asTriple().matches(this.triple)) {
l.remove();
System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] TRIPLE MAP JUST REMOVED!!! ");
System.out.println("");
return this.transform(eltPB);//eltPB;
}
}
return eltPB;
}
But I could not figure out how to remove the associated FILTER when transform(ElementFilter arg0, Expr arg1) as below
To remove a filter altogether you need to delete the ElementFilter object from the AST (abstract syntax tree). You can't do that inside the transform/ElementFilter.
It means looking in the element containing the ElementFilter which will be in a ElementGroup of some kind, probably as part of an ElementUnion.
An alternative is to replace the filter expression with a no-op like
FILTER(true)
and live with that.
Andy
@Override
public Element transform(ElementFilter arg0, Expr arg1) {
//...get the variables of the triple pattern that we want to delete
Set<Var> tpVars = new HashSet();
Node subj = this.triple.getSubject();
if (subj.isVariable()) {
tpVars.add((Var) subj);
}
Node pred = this.triple.getPredicate();
if (pred.isVariable()) {
tpVars.add((Var) pred);
}
Node obj = this.triple.getObject();
if (obj.isVariable()) {
tpVars.add((Var) obj);
}
//...get the variables of the FILTER expression
Set<Var> expVars = arg1.getVarsMentioned();
//...check whether the FILTER expression contains any of the triple pattern variable
for (Var var : expVars) {
//..if it does then we have to delete the entire FILTER expression
if (tpVars.contains(var)) {
System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter arg0)] FILTER TO BE REMOVED!!!HOW? ");
System.out.println("");
}
}
return arg0;
}
It appears to me that I am at the same point of the previous approach.
What am I doing wrong or missing? Or what I should ready to figure it out?
Thank you very much for your kind help and support.
Best Regards,
Carlo
On 29 Jan 2016, at 10:32, Andy Seaborne <an...@apache.org>> wrote:
You'll still have to clean up structures. SPIN for this is encoding the query in RDF but the rewriting of that structure needs the same (in the abstract) processing. You may be able to do it with a series of SPARQL Updates (that's speculation).
Andy
On 29/01/16 00:26, Carlo.Allocca wrote:
Dear Martynas,
Thank you very much for your help.
At the moment, I am trying what Andy suggested.
I hope to make it. Otherwise, I will look at SPIN API.
Many Thanks,
Best Regards,
Carlo
On 28 Jan 2016, at 23:48, Martynas Jusevičius <ma...@graphity.org>> wrote:
You could do it using SPIN API as well: http://spinrdf.org/sp.html
On Thu, Jan 28, 2016 at 7:39 PM, Carlo.Allocca <ca...@open.ac.uk>> wrote:
Dear Andy,
Thank you very much for your promtly reply.
I need a little bit of exploring and thinking to apply what you suggested.
Indeed, I will look at each single info you pointed out.
I will keep this thread updated.
Many Thanks,
Best Regards,
Carlo
On 28 Jan 2016, at 18:29, Andy Seaborne <an...@apache.org>> wrote:
The approach I would take is to do this is multiple passes:
1/ remove from ElementPathBlock
2/ Look for elements that are now "empty"
e.g ElementFilter with empty
but also as there one arm of a UNION.
(2) is only one pass as the rewrite is done bottom up.
I would do this as a transformation rather than modifying the syntax tree in place.
org.apache.jena.sparql.syntax.syntaxtransform
See also
ElementTransformCleanGroupsOfOne
which might be helpful to understand - its doing something different though.
It might be easier to work on the algebra, it's more regular. Then use OpAsQuery to turn algebnra into a Query.
I could not figure out how to remove the associated FILTER
when visit(ElementFilter el) as below.
because you need to alter the ElementUnion which holds the ElementFilter.
{...} UNION {} will include a blank row for the {} on the right hand side.
Andy
On 28/01/16 13:14, Carlo.Allocca wrote:
Dear All,
I am using Jena for my project and I would like to submit the following question: How to remove consistently a triple pattern given a SPARQL query?
EXAMPLE:
For example, considering the query “qString1” and the tp=“?boss ex:isBossOf ?ind .”
I need to remove tp from qString1, obtaining qString1. For “Consistently” I mean that the clause FILTER gets affected (as it contains var that appears in the triple pattern too), therefore it needs to be deleted too.
String qString1 =
" SELECT DISTINCT ?ind ?boss ?g where "
+ "{ "
+ " ?ind rdf:type ex:AssociatedResearcher ."
+ " {?ind rdf:type ?z. } UNION "
+ " {?boss ex:isBossOf ?ind . Filter(?boss=\”rossi\”)} "
+ "}";
String qString2 =
" SELECT DISTINCT ?ind ?boss ?g “
+ “WHERE "
+ "{ "
+ " ?ind rdf:type ex:AssociatedResearcher ."
+ " {?ind rdf:type ?z. } UNION "
+ " {} "
+ "}";
The solution that I am trying to implement is based on a visitor “SQRemoveTripleVisitor extends ElementVisitorBase”.
It is quite straightforward to remove the triple pattern when visit(ElementPathBlock el)
@Override
public void visit(ElementPathBlock el) {
if (el == null) {
throw new IllegalStateException("[SQRemoveTripleVisitor::visit(ElementPathBlock el)] The ElementPathBlock is null!!");
}
ListIterator<TriplePath> it = el.getPattern().iterator();
while (it.hasNext()) {
final TriplePath tp1 = it.next();
if (this.tp != null) {
if (this.tp.matches(tp1.asTriple())) {
it.remove();
}
}
}
}
I could not figure out how to remove the associated FILTER when visit(ElementFilter el) as below.
@Override
public void visit(ElementFilter el) {
//...get the variables of the FILTER expression
Expr filterExp = el.getExpr();//.getVarsMentioned().contains(el);
Set<Var> expVars = filterExp.getVarsMentioned();
//...get the variables of the triple pattern that we want to delete
Set<Var> tpVars = new HashSet();
Node subj = this.tp.getSubject();
if (subj.isVariable()) {
tpVars.add((Var) subj);
}
Node pred = this.tp.getPredicate();
if (pred.isVariable()) {
tpVars.add((Var) pred);
}
Node obj = this.tp.getObject();
if (obj.isVariable()) {
tpVars.add((Var) obj);
}
//...check whether the FILTER expression contains any of the triple pattern’s variable
for(Var var:expVars){
//…if it does then we have to delete the entire FILTER expression
if(tpVars.contains(var)){
System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter el)] I NEED TO REMOVE THE FILTER!!!!!! ");
}
}
}
Please, may I ask for any help or idea on how to remove the filter?
Many Thanks in advance.
Best Regards,
Carlo
-- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
Re: How to remove consistently a triple pattern given a SPARQL query?
Posted by Andy Seaborne <an...@apache.org>.
On 29/01/16 12:57, Carlo.Allocca wrote:
> Dear Andy and All,
>
> I tried to use as many suggested info as I could. As result, I obtained the following:
>
> I am implementing a public class RemoveOpTransform implements ElementTransform. And, again It is quite straightforward to remove the triple pattern from the ElementPathBlock
>
> @Override
> public Element transform(ElementPathBlock eltPB) {
The idea of the transform design is to not change the inoput but to
create a new copy if you change it. If you don't change it you can
return the input.
>
> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] " + eltPB.toString());
> Iterator<TriplePath> l = eltPB.patternElts();
> while (l.hasNext()) {
> TriplePath tp = l.next();
> if (tp.asTriple().matches(this.triple)) {
> l.remove();
> System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] TRIPLE MAP JUST REMOVED!!! ");
> System.out.println("");
> return this.transform(eltPB);//eltPB;
> }
> }
> return eltPB;
> }
>
> But I could not figure out how to remove the associated FILTER when transform(ElementFilter arg0, Expr arg1) as below
To remove a filter altogether you need to delete the ElementFilter
object from the AST (abstract syntax tree). You can't do that inside
the transform/ElementFilter.
It means looking in the element containing the ElementFilter which will
be in a ElementGroup of some kind, probably as part of an ElementUnion.
An alternative is to replace the filter expression with a no-op like
FILTER(true)
and live with that.
Andy
>
> @Override
> public Element transform(ElementFilter arg0, Expr arg1) {
>
> //...get the variables of the triple pattern that we want to delete
> Set<Var> tpVars = new HashSet();
> Node subj = this.triple.getSubject();
> if (subj.isVariable()) {
> tpVars.add((Var) subj);
> }
> Node pred = this.triple.getPredicate();
> if (pred.isVariable()) {
> tpVars.add((Var) pred);
> }
> Node obj = this.triple.getObject();
> if (obj.isVariable()) {
> tpVars.add((Var) obj);
> }
>
> //...get the variables of the FILTER expression
> Set<Var> expVars = arg1.getVarsMentioned();
>
> //...check whether the FILTER expression contains any of the triple pattern variable
> for (Var var : expVars) {
> //..if it does then we have to delete the entire FILTER expression
> if (tpVars.contains(var)) {
> System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter arg0)] FILTER TO BE REMOVED!!!HOW? ");
> System.out.println("");
> }
> }
>
> return arg0;
> }
>
> It appears to me that I am at the same point of the previous approach.
> What am I doing wrong or missing? Or what I should ready to figure it out?
>
> Thank you very much for your kind help and support.
>
> Best Regards,
> Carlo
>
>
>
>
>> On 29 Jan 2016, at 10:32, Andy Seaborne <an...@apache.org> wrote:
>>
>> You'll still have to clean up structures. SPIN for this is encoding the query in RDF but the rewriting of that structure needs the same (in the abstract) processing. You may be able to do it with a series of SPARQL Updates (that's speculation).
>>
>> Andy
>>
>> On 29/01/16 00:26, Carlo.Allocca wrote:
>>> Dear Martynas,
>>>
>>>
>>> Thank you very much for your help.
>>> At the moment, I am trying what Andy suggested.
>>> I hope to make it. Otherwise, I will look at SPIN API.
>>>
>>> Many Thanks,
>>> Best Regards,
>>> Carlo
>>>
>>>
>>>> On 28 Jan 2016, at 23:48, Martynas Jusevičius <ma...@graphity.org> wrote:
>>>>
>>>> You could do it using SPIN API as well: http://spinrdf.org/sp.html
>>>>
>>>> On Thu, Jan 28, 2016 at 7:39 PM, Carlo.Allocca <ca...@open.ac.uk> wrote:
>>>>> Dear Andy,
>>>>>
>>>>> Thank you very much for your promtly reply.
>>>>>
>>>>> I need a little bit of exploring and thinking to apply what you suggested.
>>>>> Indeed, I will look at each single info you pointed out.
>>>>>
>>>>> I will keep this thread updated.
>>>>>
>>>>> Many Thanks,
>>>>> Best Regards,
>>>>> Carlo
>>>>>
>>>>>> On 28 Jan 2016, at 18:29, Andy Seaborne <an...@apache.org> wrote:
>>>>>>
>>>>>> The approach I would take is to do this is multiple passes:
>>>>>>
>>>>>> 1/ remove from ElementPathBlock
>>>>>>
>>>>>> 2/ Look for elements that are now "empty"
>>>>>> e.g ElementFilter with empty
>>>>>> but also as there one arm of a UNION.
>>>>>>
>>>>>> (2) is only one pass as the rewrite is done bottom up.
>>>>>>
>>>>>>
>>>>>> I would do this as a transformation rather than modifying the syntax tree in place.
>>>>>>
>>>>>> org.apache.jena.sparql.syntax.syntaxtransform
>>>>>>
>>>>>>
>>>>>> See also
>>>>>> ElementTransformCleanGroupsOfOne
>>>>>>
>>>>>> which might be helpful to understand - its doing something different though.
>>>>>>
>>>>>> It might be easier to work on the algebra, it's more regular. Then use OpAsQuery to turn algebnra into a Query.
>>>>>>
>>>>>>> I could not figure out how to remove the associated FILTER
>>>>>>> when visit(ElementFilter el) as below.
>>>>>>
>>>>>> because you need to alter the ElementUnion which holds the ElementFilter.
>>>>>>
>>>>>> {...} UNION {} will include a blank row for the {} on the right hand side.
>>>>>>
>>>>>> Andy
>>>>>>
>>>>>>
>>>>>> On 28/01/16 13:14, Carlo.Allocca wrote:
>>>>>>> Dear All,
>>>>>>>
>>>>>>> I am using Jena for my project and I would like to submit the following question: How to remove consistently a triple pattern given a SPARQL query?
>>>>>>>
>>>>>>> EXAMPLE:
>>>>>>>
>>>>>>> For example, considering the query “qString1” and the tp=“?boss ex:isBossOf ?ind .”
>>>>>>> I need to remove tp from qString1, obtaining qString1. For “Consistently” I mean that the clause FILTER gets affected (as it contains var that appears in the triple pattern too), therefore it needs to be deleted too.
>>>>>>>
>>>>>>> String qString1 =
>>>>>>> " SELECT DISTINCT ?ind ?boss ?g where "
>>>>>>> + "{ "
>>>>>>> + " ?ind rdf:type ex:AssociatedResearcher ."
>>>>>>> + " {?ind rdf:type ?z. } UNION "
>>>>>>> + " {?boss ex:isBossOf ?ind . Filter(?boss=\”rossi\”)} "
>>>>>>> + "}";
>>>>>>>
>>>>>>>
>>>>>>> String qString2 =
>>>>>>> " SELECT DISTINCT ?ind ?boss ?g “
>>>>>>> + “WHERE "
>>>>>>> + "{ "
>>>>>>> + " ?ind rdf:type ex:AssociatedResearcher ."
>>>>>>> + " {?ind rdf:type ?z. } UNION "
>>>>>>> + " {} "
>>>>>>> + "}";
>>>>>>>
>>>>>>> The solution that I am trying to implement is based on a visitor “SQRemoveTripleVisitor extends ElementVisitorBase”.
>>>>>>> It is quite straightforward to remove the triple pattern when visit(ElementPathBlock el)
>>>>>>>
>>>>>>> @Override
>>>>>>> public void visit(ElementPathBlock el) {
>>>>>>> if (el == null) {
>>>>>>> throw new IllegalStateException("[SQRemoveTripleVisitor::visit(ElementPathBlock el)] The ElementPathBlock is null!!");
>>>>>>> }
>>>>>>>
>>>>>>> ListIterator<TriplePath> it = el.getPattern().iterator();
>>>>>>> while (it.hasNext()) {
>>>>>>> final TriplePath tp1 = it.next();
>>>>>>>
>>>>>>> if (this.tp != null) {
>>>>>>> if (this.tp.matches(tp1.asTriple())) {
>>>>>>> it.remove();
>>>>>>> }
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>> I could not figure out how to remove the associated FILTER when visit(ElementFilter el) as below.
>>>>>>>
>>>>>>>
>>>>>>> @Override
>>>>>>> public void visit(ElementFilter el) {
>>>>>>>
>>>>>>> //...get the variables of the FILTER expression
>>>>>>> Expr filterExp = el.getExpr();//.getVarsMentioned().contains(el);
>>>>>>> Set<Var> expVars = filterExp.getVarsMentioned();
>>>>>>>
>>>>>>> //...get the variables of the triple pattern that we want to delete
>>>>>>> Set<Var> tpVars = new HashSet();
>>>>>>> Node subj = this.tp.getSubject();
>>>>>>> if (subj.isVariable()) {
>>>>>>> tpVars.add((Var) subj);
>>>>>>> }
>>>>>>> Node pred = this.tp.getPredicate();
>>>>>>> if (pred.isVariable()) {
>>>>>>> tpVars.add((Var) pred);
>>>>>>> }
>>>>>>> Node obj = this.tp.getObject();
>>>>>>> if (obj.isVariable()) {
>>>>>>> tpVars.add((Var) obj);
>>>>>>> }
>>>>>>>
>>>>>>> //...check whether the FILTER expression contains any of the triple pattern’s variable
>>>>>>> for(Var var:expVars){
>>>>>>> //…if it does then we have to delete the entire FILTER expression
>>>>>>> if(tpVars.contains(var)){
>>>>>>> System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter el)] I NEED TO REMOVE THE FILTER!!!!!! ");
>>>>>>>
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>> Please, may I ask for any help or idea on how to remove the filter?
>>>>>>>
>>>>>>>
>>>>>>> Many Thanks in advance.
>>>>>>>
>>>>>>> Best Regards,
>>>>>>> Carlo
>>>>>>>
>>>>>>>
>>>>>>> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>>>>>>>
>>>>>>
>>>>>
>>>
>>
>
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Dear Andy and All,
I tried to use as many suggested info as I could. As result, I obtained the following:
I am implementing a public class RemoveOpTransform implements ElementTransform. And, again It is quite straightforward to remove the triple pattern from the ElementPathBlock
@Override
public Element transform(ElementPathBlock eltPB) {
System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] " + eltPB.toString());
Iterator<TriplePath> l = eltPB.patternElts();
while (l.hasNext()) {
TriplePath tp = l.next();
if (tp.asTriple().matches(this.triple)) {
l.remove();
System.out.println("[RemoveOpTransform::transform(ElementPathBlock arg0)] TRIPLE MAP JUST REMOVED!!! ");
System.out.println("");
return this.transform(eltPB);//eltPB;
}
}
return eltPB;
}
But I could not figure out how to remove the associated FILTER when transform(ElementFilter arg0, Expr arg1) as below
@Override
public Element transform(ElementFilter arg0, Expr arg1) {
//...get the variables of the triple pattern that we want to delete
Set<Var> tpVars = new HashSet();
Node subj = this.triple.getSubject();
if (subj.isVariable()) {
tpVars.add((Var) subj);
}
Node pred = this.triple.getPredicate();
if (pred.isVariable()) {
tpVars.add((Var) pred);
}
Node obj = this.triple.getObject();
if (obj.isVariable()) {
tpVars.add((Var) obj);
}
//...get the variables of the FILTER expression
Set<Var> expVars = arg1.getVarsMentioned();
//...check whether the FILTER expression contains any of the triple pattern variable
for (Var var : expVars) {
//..if it does then we have to delete the entire FILTER expression
if (tpVars.contains(var)) {
System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter arg0)] FILTER TO BE REMOVED!!!HOW? ");
System.out.println("");
}
}
return arg0;
}
It appears to me that I am at the same point of the previous approach.
What am I doing wrong or missing? Or what I should ready to figure it out?
Thank you very much for your kind help and support.
Best Regards,
Carlo
> On 29 Jan 2016, at 10:32, Andy Seaborne <an...@apache.org> wrote:
>
> You'll still have to clean up structures. SPIN for this is encoding the query in RDF but the rewriting of that structure needs the same (in the abstract) processing. You may be able to do it with a series of SPARQL Updates (that's speculation).
>
> Andy
>
> On 29/01/16 00:26, Carlo.Allocca wrote:
>> Dear Martynas,
>>
>>
>> Thank you very much for your help.
>> At the moment, I am trying what Andy suggested.
>> I hope to make it. Otherwise, I will look at SPIN API.
>>
>> Many Thanks,
>> Best Regards,
>> Carlo
>>
>>
>>> On 28 Jan 2016, at 23:48, Martynas Jusevičius <ma...@graphity.org> wrote:
>>>
>>> You could do it using SPIN API as well: http://spinrdf.org/sp.html
>>>
>>> On Thu, Jan 28, 2016 at 7:39 PM, Carlo.Allocca <ca...@open.ac.uk> wrote:
>>>> Dear Andy,
>>>>
>>>> Thank you very much for your promtly reply.
>>>>
>>>> I need a little bit of exploring and thinking to apply what you suggested.
>>>> Indeed, I will look at each single info you pointed out.
>>>>
>>>> I will keep this thread updated.
>>>>
>>>> Many Thanks,
>>>> Best Regards,
>>>> Carlo
>>>>
>>>>> On 28 Jan 2016, at 18:29, Andy Seaborne <an...@apache.org> wrote:
>>>>>
>>>>> The approach I would take is to do this is multiple passes:
>>>>>
>>>>> 1/ remove from ElementPathBlock
>>>>>
>>>>> 2/ Look for elements that are now "empty"
>>>>> e.g ElementFilter with empty
>>>>> but also as there one arm of a UNION.
>>>>>
>>>>> (2) is only one pass as the rewrite is done bottom up.
>>>>>
>>>>>
>>>>> I would do this as a transformation rather than modifying the syntax tree in place.
>>>>>
>>>>> org.apache.jena.sparql.syntax.syntaxtransform
>>>>>
>>>>>
>>>>> See also
>>>>> ElementTransformCleanGroupsOfOne
>>>>>
>>>>> which might be helpful to understand - its doing something different though.
>>>>>
>>>>> It might be easier to work on the algebra, it's more regular. Then use OpAsQuery to turn algebnra into a Query.
>>>>>
>>>>>> I could not figure out how to remove the associated FILTER
>>>>>> when visit(ElementFilter el) as below.
>>>>>
>>>>> because you need to alter the ElementUnion which holds the ElementFilter.
>>>>>
>>>>> {...} UNION {} will include a blank row for the {} on the right hand side.
>>>>>
>>>>> Andy
>>>>>
>>>>>
>>>>> On 28/01/16 13:14, Carlo.Allocca wrote:
>>>>>> Dear All,
>>>>>>
>>>>>> I am using Jena for my project and I would like to submit the following question: How to remove consistently a triple pattern given a SPARQL query?
>>>>>>
>>>>>> EXAMPLE:
>>>>>>
>>>>>> For example, considering the query “qString1” and the tp=“?boss ex:isBossOf ?ind .”
>>>>>> I need to remove tp from qString1, obtaining qString1. For “Consistently” I mean that the clause FILTER gets affected (as it contains var that appears in the triple pattern too), therefore it needs to be deleted too.
>>>>>>
>>>>>> String qString1 =
>>>>>> " SELECT DISTINCT ?ind ?boss ?g where "
>>>>>> + "{ "
>>>>>> + " ?ind rdf:type ex:AssociatedResearcher ."
>>>>>> + " {?ind rdf:type ?z. } UNION "
>>>>>> + " {?boss ex:isBossOf ?ind . Filter(?boss=\”rossi\”)} "
>>>>>> + "}";
>>>>>>
>>>>>>
>>>>>> String qString2 =
>>>>>> " SELECT DISTINCT ?ind ?boss ?g “
>>>>>> + “WHERE "
>>>>>> + "{ "
>>>>>> + " ?ind rdf:type ex:AssociatedResearcher ."
>>>>>> + " {?ind rdf:type ?z. } UNION "
>>>>>> + " {} "
>>>>>> + "}";
>>>>>>
>>>>>> The solution that I am trying to implement is based on a visitor “SQRemoveTripleVisitor extends ElementVisitorBase”.
>>>>>> It is quite straightforward to remove the triple pattern when visit(ElementPathBlock el)
>>>>>>
>>>>>> @Override
>>>>>> public void visit(ElementPathBlock el) {
>>>>>> if (el == null) {
>>>>>> throw new IllegalStateException("[SQRemoveTripleVisitor::visit(ElementPathBlock el)] The ElementPathBlock is null!!");
>>>>>> }
>>>>>>
>>>>>> ListIterator<TriplePath> it = el.getPattern().iterator();
>>>>>> while (it.hasNext()) {
>>>>>> final TriplePath tp1 = it.next();
>>>>>>
>>>>>> if (this.tp != null) {
>>>>>> if (this.tp.matches(tp1.asTriple())) {
>>>>>> it.remove();
>>>>>> }
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> }
>>>>>>
>>>>>> I could not figure out how to remove the associated FILTER when visit(ElementFilter el) as below.
>>>>>>
>>>>>>
>>>>>> @Override
>>>>>> public void visit(ElementFilter el) {
>>>>>>
>>>>>> //...get the variables of the FILTER expression
>>>>>> Expr filterExp = el.getExpr();//.getVarsMentioned().contains(el);
>>>>>> Set<Var> expVars = filterExp.getVarsMentioned();
>>>>>>
>>>>>> //...get the variables of the triple pattern that we want to delete
>>>>>> Set<Var> tpVars = new HashSet();
>>>>>> Node subj = this.tp.getSubject();
>>>>>> if (subj.isVariable()) {
>>>>>> tpVars.add((Var) subj);
>>>>>> }
>>>>>> Node pred = this.tp.getPredicate();
>>>>>> if (pred.isVariable()) {
>>>>>> tpVars.add((Var) pred);
>>>>>> }
>>>>>> Node obj = this.tp.getObject();
>>>>>> if (obj.isVariable()) {
>>>>>> tpVars.add((Var) obj);
>>>>>> }
>>>>>>
>>>>>> //...check whether the FILTER expression contains any of the triple pattern’s variable
>>>>>> for(Var var:expVars){
>>>>>> //…if it does then we have to delete the entire FILTER expression
>>>>>> if(tpVars.contains(var)){
>>>>>> System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter el)] I NEED TO REMOVE THE FILTER!!!!!! ");
>>>>>>
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> }
>>>>>>
>>>>>> Please, may I ask for any help or idea on how to remove the filter?
>>>>>>
>>>>>>
>>>>>> Many Thanks in advance.
>>>>>>
>>>>>> Best Regards,
>>>>>> Carlo
>>>>>>
>>>>>>
>>>>>> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>>>>>>
>>>>>
>>>>
>>
>
Re: How to remove consistently a triple pattern given a SPARQL query?
Posted by Andy Seaborne <an...@apache.org>.
You'll still have to clean up structures. SPIN for this is encoding the
query in RDF but the rewriting of that structure needs the same (in the
abstract) processing. You may be able to do it with a series of SPARQL
Updates (that's speculation).
Andy
On 29/01/16 00:26, Carlo.Allocca wrote:
> Dear Martynas,
>
>
> Thank you very much for your help.
> At the moment, I am trying what Andy suggested.
> I hope to make it. Otherwise, I will look at SPIN API.
>
> Many Thanks,
> Best Regards,
> Carlo
>
>
>> On 28 Jan 2016, at 23:48, Martynas Jusevičius <ma...@graphity.org> wrote:
>>
>> You could do it using SPIN API as well: http://spinrdf.org/sp.html
>>
>> On Thu, Jan 28, 2016 at 7:39 PM, Carlo.Allocca <ca...@open.ac.uk> wrote:
>>> Dear Andy,
>>>
>>> Thank you very much for your promtly reply.
>>>
>>> I need a little bit of exploring and thinking to apply what you suggested.
>>> Indeed, I will look at each single info you pointed out.
>>>
>>> I will keep this thread updated.
>>>
>>> Many Thanks,
>>> Best Regards,
>>> Carlo
>>>
>>>> On 28 Jan 2016, at 18:29, Andy Seaborne <an...@apache.org> wrote:
>>>>
>>>> The approach I would take is to do this is multiple passes:
>>>>
>>>> 1/ remove from ElementPathBlock
>>>>
>>>> 2/ Look for elements that are now "empty"
>>>> e.g ElementFilter with empty
>>>> but also as there one arm of a UNION.
>>>>
>>>> (2) is only one pass as the rewrite is done bottom up.
>>>>
>>>>
>>>> I would do this as a transformation rather than modifying the syntax tree in place.
>>>>
>>>> org.apache.jena.sparql.syntax.syntaxtransform
>>>>
>>>>
>>>> See also
>>>> ElementTransformCleanGroupsOfOne
>>>>
>>>> which might be helpful to understand - its doing something different though.
>>>>
>>>> It might be easier to work on the algebra, it's more regular. Then use OpAsQuery to turn algebnra into a Query.
>>>>
>>>>> I could not figure out how to remove the associated FILTER
>>>>> when visit(ElementFilter el) as below.
>>>>
>>>> because you need to alter the ElementUnion which holds the ElementFilter.
>>>>
>>>> {...} UNION {} will include a blank row for the {} on the right hand side.
>>>>
>>>> Andy
>>>>
>>>>
>>>> On 28/01/16 13:14, Carlo.Allocca wrote:
>>>>> Dear All,
>>>>>
>>>>> I am using Jena for my project and I would like to submit the following question: How to remove consistently a triple pattern given a SPARQL query?
>>>>>
>>>>> EXAMPLE:
>>>>>
>>>>> For example, considering the query “qString1” and the tp=“?boss ex:isBossOf ?ind .”
>>>>> I need to remove tp from qString1, obtaining qString1. For “Consistently” I mean that the clause FILTER gets affected (as it contains var that appears in the triple pattern too), therefore it needs to be deleted too.
>>>>>
>>>>> String qString1 =
>>>>> " SELECT DISTINCT ?ind ?boss ?g where "
>>>>> + "{ "
>>>>> + " ?ind rdf:type ex:AssociatedResearcher ."
>>>>> + " {?ind rdf:type ?z. } UNION "
>>>>> + " {?boss ex:isBossOf ?ind . Filter(?boss=\”rossi\”)} "
>>>>> + "}";
>>>>>
>>>>>
>>>>> String qString2 =
>>>>> " SELECT DISTINCT ?ind ?boss ?g “
>>>>> + “WHERE "
>>>>> + "{ "
>>>>> + " ?ind rdf:type ex:AssociatedResearcher ."
>>>>> + " {?ind rdf:type ?z. } UNION "
>>>>> + " {} "
>>>>> + "}";
>>>>>
>>>>> The solution that I am trying to implement is based on a visitor “SQRemoveTripleVisitor extends ElementVisitorBase”.
>>>>> It is quite straightforward to remove the triple pattern when visit(ElementPathBlock el)
>>>>>
>>>>> @Override
>>>>> public void visit(ElementPathBlock el) {
>>>>> if (el == null) {
>>>>> throw new IllegalStateException("[SQRemoveTripleVisitor::visit(ElementPathBlock el)] The ElementPathBlock is null!!");
>>>>> }
>>>>>
>>>>> ListIterator<TriplePath> it = el.getPattern().iterator();
>>>>> while (it.hasNext()) {
>>>>> final TriplePath tp1 = it.next();
>>>>>
>>>>> if (this.tp != null) {
>>>>> if (this.tp.matches(tp1.asTriple())) {
>>>>> it.remove();
>>>>> }
>>>>> }
>>>>> }
>>>>>
>>>>> }
>>>>>
>>>>> I could not figure out how to remove the associated FILTER when visit(ElementFilter el) as below.
>>>>>
>>>>>
>>>>> @Override
>>>>> public void visit(ElementFilter el) {
>>>>>
>>>>> //...get the variables of the FILTER expression
>>>>> Expr filterExp = el.getExpr();//.getVarsMentioned().contains(el);
>>>>> Set<Var> expVars = filterExp.getVarsMentioned();
>>>>>
>>>>> //...get the variables of the triple pattern that we want to delete
>>>>> Set<Var> tpVars = new HashSet();
>>>>> Node subj = this.tp.getSubject();
>>>>> if (subj.isVariable()) {
>>>>> tpVars.add((Var) subj);
>>>>> }
>>>>> Node pred = this.tp.getPredicate();
>>>>> if (pred.isVariable()) {
>>>>> tpVars.add((Var) pred);
>>>>> }
>>>>> Node obj = this.tp.getObject();
>>>>> if (obj.isVariable()) {
>>>>> tpVars.add((Var) obj);
>>>>> }
>>>>>
>>>>> //...check whether the FILTER expression contains any of the triple pattern’s variable
>>>>> for(Var var:expVars){
>>>>> //…if it does then we have to delete the entire FILTER expression
>>>>> if(tpVars.contains(var)){
>>>>> System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter el)] I NEED TO REMOVE THE FILTER!!!!!! ");
>>>>>
>>>>> }
>>>>> }
>>>>>
>>>>> }
>>>>>
>>>>> Please, may I ask for any help or idea on how to remove the filter?
>>>>>
>>>>>
>>>>> Many Thanks in advance.
>>>>>
>>>>> Best Regards,
>>>>> Carlo
>>>>>
>>>>>
>>>>> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>>>>>
>>>>
>>>
>
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Dear Martynas,
Thank you very much for your help.
At the moment, I am trying what Andy suggested.
I hope to make it. Otherwise, I will look at SPIN API.
Many Thanks,
Best Regards,
Carlo
> On 28 Jan 2016, at 23:48, Martynas Jusevičius <ma...@graphity.org> wrote:
>
> You could do it using SPIN API as well: http://spinrdf.org/sp.html
>
> On Thu, Jan 28, 2016 at 7:39 PM, Carlo.Allocca <ca...@open.ac.uk> wrote:
>> Dear Andy,
>>
>> Thank you very much for your promtly reply.
>>
>> I need a little bit of exploring and thinking to apply what you suggested.
>> Indeed, I will look at each single info you pointed out.
>>
>> I will keep this thread updated.
>>
>> Many Thanks,
>> Best Regards,
>> Carlo
>>
>>> On 28 Jan 2016, at 18:29, Andy Seaborne <an...@apache.org> wrote:
>>>
>>> The approach I would take is to do this is multiple passes:
>>>
>>> 1/ remove from ElementPathBlock
>>>
>>> 2/ Look for elements that are now "empty"
>>> e.g ElementFilter with empty
>>> but also as there one arm of a UNION.
>>>
>>> (2) is only one pass as the rewrite is done bottom up.
>>>
>>>
>>> I would do this as a transformation rather than modifying the syntax tree in place.
>>>
>>> org.apache.jena.sparql.syntax.syntaxtransform
>>>
>>>
>>> See also
>>> ElementTransformCleanGroupsOfOne
>>>
>>> which might be helpful to understand - its doing something different though.
>>>
>>> It might be easier to work on the algebra, it's more regular. Then use OpAsQuery to turn algebnra into a Query.
>>>
>>>> I could not figure out how to remove the associated FILTER
>>>> when visit(ElementFilter el) as below.
>>>
>>> because you need to alter the ElementUnion which holds the ElementFilter.
>>>
>>> {...} UNION {} will include a blank row for the {} on the right hand side.
>>>
>>> Andy
>>>
>>>
>>> On 28/01/16 13:14, Carlo.Allocca wrote:
>>>> Dear All,
>>>>
>>>> I am using Jena for my project and I would like to submit the following question: How to remove consistently a triple pattern given a SPARQL query?
>>>>
>>>> EXAMPLE:
>>>>
>>>> For example, considering the query “qString1” and the tp=“?boss ex:isBossOf ?ind .”
>>>> I need to remove tp from qString1, obtaining qString1. For “Consistently” I mean that the clause FILTER gets affected (as it contains var that appears in the triple pattern too), therefore it needs to be deleted too.
>>>>
>>>> String qString1 =
>>>> " SELECT DISTINCT ?ind ?boss ?g where "
>>>> + "{ "
>>>> + " ?ind rdf:type ex:AssociatedResearcher ."
>>>> + " {?ind rdf:type ?z. } UNION "
>>>> + " {?boss ex:isBossOf ?ind . Filter(?boss=\”rossi\”)} "
>>>> + "}";
>>>>
>>>>
>>>> String qString2 =
>>>> " SELECT DISTINCT ?ind ?boss ?g “
>>>> + “WHERE "
>>>> + "{ "
>>>> + " ?ind rdf:type ex:AssociatedResearcher ."
>>>> + " {?ind rdf:type ?z. } UNION "
>>>> + " {} "
>>>> + "}";
>>>>
>>>> The solution that I am trying to implement is based on a visitor “SQRemoveTripleVisitor extends ElementVisitorBase”.
>>>> It is quite straightforward to remove the triple pattern when visit(ElementPathBlock el)
>>>>
>>>> @Override
>>>> public void visit(ElementPathBlock el) {
>>>> if (el == null) {
>>>> throw new IllegalStateException("[SQRemoveTripleVisitor::visit(ElementPathBlock el)] The ElementPathBlock is null!!");
>>>> }
>>>>
>>>> ListIterator<TriplePath> it = el.getPattern().iterator();
>>>> while (it.hasNext()) {
>>>> final TriplePath tp1 = it.next();
>>>>
>>>> if (this.tp != null) {
>>>> if (this.tp.matches(tp1.asTriple())) {
>>>> it.remove();
>>>> }
>>>> }
>>>> }
>>>>
>>>> }
>>>>
>>>> I could not figure out how to remove the associated FILTER when visit(ElementFilter el) as below.
>>>>
>>>>
>>>> @Override
>>>> public void visit(ElementFilter el) {
>>>>
>>>> //...get the variables of the FILTER expression
>>>> Expr filterExp = el.getExpr();//.getVarsMentioned().contains(el);
>>>> Set<Var> expVars = filterExp.getVarsMentioned();
>>>>
>>>> //...get the variables of the triple pattern that we want to delete
>>>> Set<Var> tpVars = new HashSet();
>>>> Node subj = this.tp.getSubject();
>>>> if (subj.isVariable()) {
>>>> tpVars.add((Var) subj);
>>>> }
>>>> Node pred = this.tp.getPredicate();
>>>> if (pred.isVariable()) {
>>>> tpVars.add((Var) pred);
>>>> }
>>>> Node obj = this.tp.getObject();
>>>> if (obj.isVariable()) {
>>>> tpVars.add((Var) obj);
>>>> }
>>>>
>>>> //...check whether the FILTER expression contains any of the triple pattern’s variable
>>>> for(Var var:expVars){
>>>> //…if it does then we have to delete the entire FILTER expression
>>>> if(tpVars.contains(var)){
>>>> System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter el)] I NEED TO REMOVE THE FILTER!!!!!! ");
>>>>
>>>> }
>>>> }
>>>>
>>>> }
>>>>
>>>> Please, may I ask for any help or idea on how to remove the filter?
>>>>
>>>>
>>>> Many Thanks in advance.
>>>>
>>>> Best Regards,
>>>> Carlo
>>>>
>>>>
>>>> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>>>>
>>>
>>
Re: How to remove consistently a triple pattern given a SPARQL query?
Posted by Martynas Jusevičius <ma...@graphity.org>.
You could do it using SPIN API as well: http://spinrdf.org/sp.html
On Thu, Jan 28, 2016 at 7:39 PM, Carlo.Allocca <ca...@open.ac.uk> wrote:
> Dear Andy,
>
> Thank you very much for your promtly reply.
>
> I need a little bit of exploring and thinking to apply what you suggested.
> Indeed, I will look at each single info you pointed out.
>
> I will keep this thread updated.
>
> Many Thanks,
> Best Regards,
> Carlo
>
>> On 28 Jan 2016, at 18:29, Andy Seaborne <an...@apache.org> wrote:
>>
>> The approach I would take is to do this is multiple passes:
>>
>> 1/ remove from ElementPathBlock
>>
>> 2/ Look for elements that are now "empty"
>> e.g ElementFilter with empty
>> but also as there one arm of a UNION.
>>
>> (2) is only one pass as the rewrite is done bottom up.
>>
>>
>> I would do this as a transformation rather than modifying the syntax tree in place.
>>
>> org.apache.jena.sparql.syntax.syntaxtransform
>>
>>
>> See also
>> ElementTransformCleanGroupsOfOne
>>
>> which might be helpful to understand - its doing something different though.
>>
>> It might be easier to work on the algebra, it's more regular. Then use OpAsQuery to turn algebnra into a Query.
>>
>> > I could not figure out how to remove the associated FILTER
>> > when visit(ElementFilter el) as below.
>>
>> because you need to alter the ElementUnion which holds the ElementFilter.
>>
>> {...} UNION {} will include a blank row for the {} on the right hand side.
>>
>> Andy
>>
>>
>> On 28/01/16 13:14, Carlo.Allocca wrote:
>>> Dear All,
>>>
>>> I am using Jena for my project and I would like to submit the following question: How to remove consistently a triple pattern given a SPARQL query?
>>>
>>> EXAMPLE:
>>>
>>> For example, considering the query “qString1” and the tp=“?boss ex:isBossOf ?ind .”
>>> I need to remove tp from qString1, obtaining qString1. For “Consistently” I mean that the clause FILTER gets affected (as it contains var that appears in the triple pattern too), therefore it needs to be deleted too.
>>>
>>> String qString1 =
>>> " SELECT DISTINCT ?ind ?boss ?g where "
>>> + "{ "
>>> + " ?ind rdf:type ex:AssociatedResearcher ."
>>> + " {?ind rdf:type ?z. } UNION "
>>> + " {?boss ex:isBossOf ?ind . Filter(?boss=\”rossi\”)} "
>>> + "}";
>>>
>>>
>>> String qString2 =
>>> " SELECT DISTINCT ?ind ?boss ?g “
>>> + “WHERE "
>>> + "{ "
>>> + " ?ind rdf:type ex:AssociatedResearcher ."
>>> + " {?ind rdf:type ?z. } UNION "
>>> + " {} "
>>> + "}";
>>>
>>> The solution that I am trying to implement is based on a visitor “SQRemoveTripleVisitor extends ElementVisitorBase”.
>>> It is quite straightforward to remove the triple pattern when visit(ElementPathBlock el)
>>>
>>> @Override
>>> public void visit(ElementPathBlock el) {
>>> if (el == null) {
>>> throw new IllegalStateException("[SQRemoveTripleVisitor::visit(ElementPathBlock el)] The ElementPathBlock is null!!");
>>> }
>>>
>>> ListIterator<TriplePath> it = el.getPattern().iterator();
>>> while (it.hasNext()) {
>>> final TriplePath tp1 = it.next();
>>>
>>> if (this.tp != null) {
>>> if (this.tp.matches(tp1.asTriple())) {
>>> it.remove();
>>> }
>>> }
>>> }
>>>
>>> }
>>>
>>> I could not figure out how to remove the associated FILTER when visit(ElementFilter el) as below.
>>>
>>>
>>> @Override
>>> public void visit(ElementFilter el) {
>>>
>>> //...get the variables of the FILTER expression
>>> Expr filterExp = el.getExpr();//.getVarsMentioned().contains(el);
>>> Set<Var> expVars = filterExp.getVarsMentioned();
>>>
>>> //...get the variables of the triple pattern that we want to delete
>>> Set<Var> tpVars = new HashSet();
>>> Node subj = this.tp.getSubject();
>>> if (subj.isVariable()) {
>>> tpVars.add((Var) subj);
>>> }
>>> Node pred = this.tp.getPredicate();
>>> if (pred.isVariable()) {
>>> tpVars.add((Var) pred);
>>> }
>>> Node obj = this.tp.getObject();
>>> if (obj.isVariable()) {
>>> tpVars.add((Var) obj);
>>> }
>>>
>>> //...check whether the FILTER expression contains any of the triple pattern’s variable
>>> for(Var var:expVars){
>>> //…if it does then we have to delete the entire FILTER expression
>>> if(tpVars.contains(var)){
>>> System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter el)] I NEED TO REMOVE THE FILTER!!!!!! ");
>>>
>>> }
>>> }
>>>
>>> }
>>>
>>> Please, may I ask for any help or idea on how to remove the filter?
>>>
>>>
>>> Many Thanks in advance.
>>>
>>> Best Regards,
>>> Carlo
>>>
>>>
>>> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>>>
>>
>
Re: How to remove consistently a triple pattern given a SPARQL
query?
Posted by "Carlo.Allocca" <ca...@open.ac.uk>.
Dear Andy,
Thank you very much for your promtly reply.
I need a little bit of exploring and thinking to apply what you suggested.
Indeed, I will look at each single info you pointed out.
I will keep this thread updated.
Many Thanks,
Best Regards,
Carlo
> On 28 Jan 2016, at 18:29, Andy Seaborne <an...@apache.org> wrote:
>
> The approach I would take is to do this is multiple passes:
>
> 1/ remove from ElementPathBlock
>
> 2/ Look for elements that are now "empty"
> e.g ElementFilter with empty
> but also as there one arm of a UNION.
>
> (2) is only one pass as the rewrite is done bottom up.
>
>
> I would do this as a transformation rather than modifying the syntax tree in place.
>
> org.apache.jena.sparql.syntax.syntaxtransform
>
>
> See also
> ElementTransformCleanGroupsOfOne
>
> which might be helpful to understand - its doing something different though.
>
> It might be easier to work on the algebra, it's more regular. Then use OpAsQuery to turn algebnra into a Query.
>
> > I could not figure out how to remove the associated FILTER
> > when visit(ElementFilter el) as below.
>
> because you need to alter the ElementUnion which holds the ElementFilter.
>
> {...} UNION {} will include a blank row for the {} on the right hand side.
>
> Andy
>
>
> On 28/01/16 13:14, Carlo.Allocca wrote:
>> Dear All,
>>
>> I am using Jena for my project and I would like to submit the following question: How to remove consistently a triple pattern given a SPARQL query?
>>
>> EXAMPLE:
>>
>> For example, considering the query “qString1” and the tp=“?boss ex:isBossOf ?ind .”
>> I need to remove tp from qString1, obtaining qString1. For “Consistently” I mean that the clause FILTER gets affected (as it contains var that appears in the triple pattern too), therefore it needs to be deleted too.
>>
>> String qString1 =
>> " SELECT DISTINCT ?ind ?boss ?g where "
>> + "{ "
>> + " ?ind rdf:type ex:AssociatedResearcher ."
>> + " {?ind rdf:type ?z. } UNION "
>> + " {?boss ex:isBossOf ?ind . Filter(?boss=\”rossi\”)} "
>> + "}";
>>
>>
>> String qString2 =
>> " SELECT DISTINCT ?ind ?boss ?g “
>> + “WHERE "
>> + "{ "
>> + " ?ind rdf:type ex:AssociatedResearcher ."
>> + " {?ind rdf:type ?z. } UNION "
>> + " {} "
>> + "}";
>>
>> The solution that I am trying to implement is based on a visitor “SQRemoveTripleVisitor extends ElementVisitorBase”.
>> It is quite straightforward to remove the triple pattern when visit(ElementPathBlock el)
>>
>> @Override
>> public void visit(ElementPathBlock el) {
>> if (el == null) {
>> throw new IllegalStateException("[SQRemoveTripleVisitor::visit(ElementPathBlock el)] The ElementPathBlock is null!!");
>> }
>>
>> ListIterator<TriplePath> it = el.getPattern().iterator();
>> while (it.hasNext()) {
>> final TriplePath tp1 = it.next();
>>
>> if (this.tp != null) {
>> if (this.tp.matches(tp1.asTriple())) {
>> it.remove();
>> }
>> }
>> }
>>
>> }
>>
>> I could not figure out how to remove the associated FILTER when visit(ElementFilter el) as below.
>>
>>
>> @Override
>> public void visit(ElementFilter el) {
>>
>> //...get the variables of the FILTER expression
>> Expr filterExp = el.getExpr();//.getVarsMentioned().contains(el);
>> Set<Var> expVars = filterExp.getVarsMentioned();
>>
>> //...get the variables of the triple pattern that we want to delete
>> Set<Var> tpVars = new HashSet();
>> Node subj = this.tp.getSubject();
>> if (subj.isVariable()) {
>> tpVars.add((Var) subj);
>> }
>> Node pred = this.tp.getPredicate();
>> if (pred.isVariable()) {
>> tpVars.add((Var) pred);
>> }
>> Node obj = this.tp.getObject();
>> if (obj.isVariable()) {
>> tpVars.add((Var) obj);
>> }
>>
>> //...check whether the FILTER expression contains any of the triple pattern’s variable
>> for(Var var:expVars){
>> //…if it does then we have to delete the entire FILTER expression
>> if(tpVars.contains(var)){
>> System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter el)] I NEED TO REMOVE THE FILTER!!!!!! ");
>>
>> }
>> }
>>
>> }
>>
>> Please, may I ask for any help or idea on how to remove the filter?
>>
>>
>> Many Thanks in advance.
>>
>> Best Regards,
>> Carlo
>>
>>
>> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>>
>
Re: How to remove consistently a triple pattern given a SPARQL query?
Posted by Andy Seaborne <an...@apache.org>.
The approach I would take is to do this is multiple passes:
1/ remove from ElementPathBlock
2/ Look for elements that are now "empty"
e.g ElementFilter with empty
but also as there one arm of a UNION.
(2) is only one pass as the rewrite is done bottom up.
I would do this as a transformation rather than modifying the syntax
tree in place.
org.apache.jena.sparql.syntax.syntaxtransform
See also
ElementTransformCleanGroupsOfOne
which might be helpful to understand - its doing something different though.
It might be easier to work on the algebra, it's more regular. Then use
OpAsQuery to turn algebnra into a Query.
> I could not figure out how to remove the associated FILTER
> when visit(ElementFilter el) as below.
because you need to alter the ElementUnion which holds the ElementFilter.
{...} UNION {} will include a blank row for the {} on the right hand side.
Andy
On 28/01/16 13:14, Carlo.Allocca wrote:
> Dear All,
>
> I am using Jena for my project and I would like to submit the following question: How to remove consistently a triple pattern given a SPARQL query?
>
> EXAMPLE:
>
> For example, considering the query “qString1” and the tp=“?boss ex:isBossOf ?ind .”
> I need to remove tp from qString1, obtaining qString1. For “Consistently” I mean that the clause FILTER gets affected (as it contains var that appears in the triple pattern too), therefore it needs to be deleted too.
>
> String qString1 =
> " SELECT DISTINCT ?ind ?boss ?g where "
> + "{ "
> + " ?ind rdf:type ex:AssociatedResearcher ."
> + " {?ind rdf:type ?z. } UNION "
> + " {?boss ex:isBossOf ?ind . Filter(?boss=\”rossi\”)} "
> + "}";
>
>
> String qString2 =
> " SELECT DISTINCT ?ind ?boss ?g “
> + “WHERE "
> + "{ "
> + " ?ind rdf:type ex:AssociatedResearcher ."
> + " {?ind rdf:type ?z. } UNION "
> + " {} "
> + "}";
>
> The solution that I am trying to implement is based on a visitor “SQRemoveTripleVisitor extends ElementVisitorBase”.
> It is quite straightforward to remove the triple pattern when visit(ElementPathBlock el)
>
> @Override
> public void visit(ElementPathBlock el) {
> if (el == null) {
> throw new IllegalStateException("[SQRemoveTripleVisitor::visit(ElementPathBlock el)] The ElementPathBlock is null!!");
> }
>
> ListIterator<TriplePath> it = el.getPattern().iterator();
> while (it.hasNext()) {
> final TriplePath tp1 = it.next();
>
> if (this.tp != null) {
> if (this.tp.matches(tp1.asTriple())) {
> it.remove();
> }
> }
> }
>
> }
>
> I could not figure out how to remove the associated FILTER when visit(ElementFilter el) as below.
>
>
> @Override
> public void visit(ElementFilter el) {
>
> //...get the variables of the FILTER expression
> Expr filterExp = el.getExpr();//.getVarsMentioned().contains(el);
> Set<Var> expVars = filterExp.getVarsMentioned();
>
> //...get the variables of the triple pattern that we want to delete
> Set<Var> tpVars = new HashSet();
> Node subj = this.tp.getSubject();
> if (subj.isVariable()) {
> tpVars.add((Var) subj);
> }
> Node pred = this.tp.getPredicate();
> if (pred.isVariable()) {
> tpVars.add((Var) pred);
> }
> Node obj = this.tp.getObject();
> if (obj.isVariable()) {
> tpVars.add((Var) obj);
> }
>
> //...check whether the FILTER expression contains any of the triple pattern’s variable
> for(Var var:expVars){
> //…if it does then we have to delete the entire FILTER expression
> if(tpVars.contains(var)){
> System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter el)] I NEED TO REMOVE THE FILTER!!!!!! ");
>
> }
> }
>
> }
>
> Please, may I ask for any help or idea on how to remove the filter?
>
>
> Many Thanks in advance.
>
> Best Regards,
> Carlo
>
>
> -- The Open University is incorporated by Royal Charter (RC 000391), an exempt charity in England & Wales and a charity registered in Scotland (SC 038302). The Open University is authorised and regulated by the Financial Conduct Authority.
>