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 <carlo.allo...@open.ac.uk> wrote:
> 
> Dear Andy, 
> 
> 
>> On 31 Jan 2016, at 15:25, Andy Seaborne <a...@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 
>>>> <buehm...@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 
>>>>>> <buehm...@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 <carlo.allo...@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 
>>>>>>>> <a...@apache.org<mailto:a...@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 
>>>>>>>> <a...@apache.org<mailto:a...@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
>>>> 
>>> 
>> 
> 

Reply via email to