Dear Andy and Paul,

some comments follow in lines.

> On 2 Feb 2016, at 22:33, Andy Seaborne <a...@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 <carlo.allo...@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.allo...@open.ac.uk<mailto:
>>> carlo.allo...@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 <a...@apache.org<mailto:
>>> a...@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.

Reply via email to