Re: [ISSUE-62] A clean proposal with sh:Scope

Peter, so while I did not get a definite statement from you about 
whether scopes could also be templates, I assume you are at least not 
opposed to this idea. Indeed I believe it will allow to encapsulate and 
reuse recurring SPARQL queries just like the constraint templates. For 
example, sh:AllSubjectsScope would be backed by

SELECT DISTINCT ?this
WHERE {
     ?this ?anyPredicate ?anyObject .
}

The point that I am still trying to get at is that the queries that 
produce bindings are fundamentally different from those that check the 
bindings against constraint conditions. You had introduced them as 
sh:sparqlScope, and I am suggesting to extend this concept to also allow 
templates. sh:nodeShape/individualScope and sh:classShape will remain as 
before, in addition to sh:scope.

So the only remaining difference seems to be sh:shapeScope. You suggest 
we can simply point at constraints there. I have pointed out that this 
isn't always possible because these constraints in general require a 
pre-bound ?this focus node (although some do not require it). I believe 
that a clean solution to this issue is to only allow shapes as scopes 
when they are combined with another scope that produces bindings for 
?this. I have called those "filter shapes" to make this distinction 
clear. You believe that the engine can in those cases inject some 
"magic" to make sure that ?this is always bound, but that requires an 
algorithm that analyses SPARQL queries on whether they produce bindings, 
plus a rather arbitrary decision about which nodes shall be bound. But 
in the end, the situation is exactly like in my approach, that you are 
separating the binding part from the filtering part, only that you don't 
call them filter shapes.

Let's look at an example. Assume you have to scope a constraint to be 
about "every subject that has dc:author 'John Doe'". In your approach 
this would look roughly like

ex:MyShape
     sh:shapeScope [
         sh:property [
             sh:predicate dc:author ;
             sh:hasValue "John Doe" ;
         ]
     ] ;
     sh:constraint ...

Unfortunately the SPARQL behind sh:hasValue is

FILTER NOT EXISTS { ?this dc:author "John Doe" }

which a realistic code generator could only use to produce something like

SELECT ?violation
WHERE {
     FILTER (!NOT EXISTS { ?this dc:author "John Doe" })
     ... actual constraints ...
}

which doesn't work because ?this isn't bound reliably. So following the 
magic insertion it would have to be something like

SELECT ?violation
WHERE {
     {
         SELECT DISTINCT ?this
         WHERE {
             ?this a ?any .
         }
     }
     FILTER (!NOT EXISTS { ?this dc:author "John Doe" })
     ... actual constraints ...
}

which is a non-starter because it requires walking through all (typed) 
subjects in the whole model. And since there are plenty of models with 
untyped nodes, we'd need to support walking all subjects, leading to an 
iteration across all triples in the graph, only to find the few that 
actually have that dc:author. I really don't see how this approach can 
work in practice.

In my proposed design, this would look like

ex:MyShape
     sh:shape [
         sh:sparql "?this dc:author 'John Doe'" ;
     ] ;
     sh:constraint ...

which can easily be used to produce

SELECT ?violation
WHERE {
     ?this dc:author "John Doe" .
     ... actual constraints ...
}

Turned into a template it would become

ex:MyShape
     sh:shape [
         a sh:HasValueScope ;
         sh:predicate dc:author ;
         sh:hasValue "John Doe" ;
     ] ;
     sh:constraint ...

which is also understandable to non-SPARQL engines.

A remaining question is that scopes must also be evaluable in the other 
direction, with a given ?this, because someone can invoke the SHACL 
engine to only check a given focus node, and the engine needs to figure 
out whether a shape has the focus node in scope. This case is indeed 
similar to constraints. We have several options on how to resolve this. 
We could require that the SPARQL queries behind sh:scope always have to 
work both ways, e.g. ?this dc:author "John Doe" is in this category - it 
can either iterate over all ?this or it becomes an ASK query about a 
given ?this. I believe this applies to the majority of common scenarios. 
For the rare cases where this doesn't work, a scope could have a second 
SPARQL snippet, e.g. sh:sparqlFilter, that is optimized for the inverse 
direction.

Thanks,
Holger


On 6/9/15 7:49 AM, Peter F. Patel-Schneider wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
>
> I may not be understanding what you are trying to get at here.
>
> sh:sparqlScope is designed to allow SPARQL as a scope, i.e., to allow
> sofisticated users to write SPARQL code for scopes.
>
> I'm assuming that you want sh:AllSubjectsScope to be a separate kind of
> scope, which "binds" to all subjects in the graph. This would be equivalent
> to a sh:sparqlScope of ?this ?p ? v, modulo multiple binding and the extra
> variables, I think. If sh:PropertyScope is also a separate kind of scope,
> which "binds" to all properties in the graph, then I think that it can be
> handled in a similar way, again modulo multiple bindings. Efficient SPARQL
> fragments for these purposes would certainly be better, of course.
>
> So in some sense, there is no need for much special treatment for
> sh:PropertyScope or sh:AllSubjectsScope, at least if my understanding is
> correct. They could be a template, as can sh:classScope and
> sh:individualScope, except a template with no parameters and would then be
> handled with sh:shapeScope.
>
> peter
>
>
>
> On 06/08/2015 03:15 AM, Holger Knublauch wrote:> Hi Peter, could we try to
> take baby steps towards a resolution here. My first
>> question: your proposal has sh:sparqlScope - a query fragment that
>> delivers bindings for ?this. Do you agree that it makes sense to
>> generalize this to also allow templates here? This would allow us and
>> others to introduce something like sh:PropertyScope or
>> sh:AllSubjectsScope as high-level language terms without forcing users
>> to repeat the underlying SPARQL query over and over again. It would also
>> cater for other languages than SPARQL, if we decide to allow other
>> extension languages.
>>
>> Thanks, Holger
>>
>>
>> On 6/5/15 10:06 PM, Peter F. Patel-Schneider wrote:
>>> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
>>>
>>> So this ends up with scopes, filters, and constraints.  It requires
>>> that constraints do double duty, as both constraints and filters.
>>>
>>> I still think that it is cleaner for shapes to have a scope and one or
>>> more constraints only, and to have constraints be used in both places.
>>> It eliminates a construct without eliminating any expressive power.
>>>
>>> As far as binding goes there are several reasonable solutions, one of
>>> which is in essence automatically adding in a "universal" binding when
>>> required. I think that using constraints as filters is going to have
>>> the same issue anyway.
>>>
>>>
>>>
>>> Using constraints as scopes can be done without requiring double
>>> expansion in templates.   For the example you mention below, my SPARQL
>>> expansion for hasValue on rdf:type to http:/example.org/Person could
>>> be used as the scope. It is not formulated in the opposite direction.
>>>
>>>
>>> peter
>>>
>>>
>>>
>>> On 06/04/2015 04:29 PM, Holger Knublauch wrote:
>>>> On 6/5/2015 8:54, Peter F. Patel-Schneider wrote: There were already
>>>>   separate scopes for individual-based scoping and class-based
>>>> scoping.
>>>>
>>>>> Yes, my proposal is to keep sh:scopeClass and sh:nodeShape as
>>>>> syntactic sugar for the frequently needed cases that they cover.
>>>> Do you mean that there should now be a new kind of template for
>>>> scopes, and new special scopes, all separate from constraints?
>>>>
>>>>> Yes, because scopes and shapes are very different concepts. Scopes
>>>>>   produce focus nodes, while constraints validate given focus
>>>>> nodes.
>>>> Constraints are already available, and can do double duty as scopes.
>>>>   Why not use them for determining the scope of a shape particularly
>>>> as you then actually do use them for this purpose, but as filters.
>>>> I don't see what the point is of adding all this extra stuff.
>>>>
>>>>> Because they cannot always do double duty, as we had discussed
>>>>> here at length. This is due to the way that they are implemented.
>>>>> A constraint produces violation instances, but what we need are
>>>>> focus nodes. In other words, constraints look for the counter
>>>>> examples, while we would need the opposite direction to find all
>>>>> nodes that actually fit. I am surprised about your feedback,
>>>>> because your own proposal had exactly the same concept, in form of
>>>>> sh:sparqlScope. In your own example, you use it to return all
>>>>> instance of ex:Person: [ rdf:type sh:Constraint ; sh:severity
>>>>> sh:fatalError ; sh:report "SELECT ?person" ; sh:sparqlScope
>>>>> "?person rdf:type <http://example.org/Person>" ; sh:sparqlShape
>>>>> """FILTER NOT EXISTS { ?person ex:offspring ?offspring . FILTER NOT
>>>>> EXISTS { ?offspring rdf:type ex:Person . } }""" ] . If this scope
>>>>> were a constraint, then it would be formulated in the opposite
>>>>> direction "report an error if this is not an instance of
>>>>> ex:Person". All I have done is generalize your approach to allow
>>>>> sparqlScope to also be a template, and I have moved your
>>>>> sh:shapeScope into sh:filterShape. This solves the problem with
>>>>> your approach, that some constraints simply do not bind ?this. Your
>>>>> work-around was to inject some magic to bind ?this with all
>>>>> instances of rdfs:Resource, so but even this hack now can have an
>>>>> official solution: sh:ShapeScope a sh:ScopeTemplate sh:argument [
>>>>> sh:predicate sh:shape ; # becomes ?shape in the query sh:valueType
>>>>> sh:Shape ; rdfs:comment "The shape that all focus nodes must have"
>>>>> ] ; sh:sparql """ SELECT ?this WHERE { ?this a rdfs:Resource .
>>>>> FILTER sh:hasShape(?this, ?shape) } """ . And we side-step the
>>>>> question whether ?this should by default be all subjects, all
>>>>> nodes, all instances, etc. We just define a generic mechanism and
>>>>> let the model do the rest. Anyone can add their own scoping
>>>>> template. As a bonus we don't have to look into complex SPARQL
>>>>> query analysis to find out whether a query is binding ?this and
>>>>> similar unnecessary complexity that few users will understand. Hope
>>>>> this makes sense, I can elaborate further. Holger
>>>>
>>>> peter
>>>>
>>>>
>>>> On 06/03/2015 04:16 PM, Holger Knublauch wrote:
>>>>>>> I thought more about the issue of generic scopes and filters
>>>>>>> and have come up with a variation of Peter's design. Assuming
>>>>>>> we define
>>>>>>>
>>>>>>> - Scope: takes a graph as input and produces bindings for the
>>>>>>> focus node (?this)
>>>>>>>
>>>>>>> Graph -> focus nodes
>>>>>>>
>>>>>>> - Constraint: that takes a focus node as input and produces
>>>>>>> (violation) results:
>>>>>>>
>>>>>>> focus nodes -> results
>>>>>>>
>>>>>>> I think we should make Scopes an explicit concept in SHACL's
>>>>>>> RDF vocabulary, similar to how shapes are defined. There would
>>>>>>> be the following class hierarchy:
>>>>>>>
>>>>>>> sh:Scope sh:NativeScope sh:TemplateScope
>>>>>>>
>>>>>>> And native scopes can have sh:sparql (or a JS body etc).
>>>>>>> Example
>>>>>>>
>>>>>>> # Applies to all subjects that have a skos:prefLabel ex:MyShape
>>>>>>> sh:scope [ a sh:NativeScope ; # Optional rdf:type triple
>>>>>>> sh:sparql """ SELECT DISTINCT ?this WHERE { ?this
>>>>>>> skos:prefLabel ?any } """ ] ; sh:constraint [ a
>>>>>>> ex:UniqueLanguageConstraint ; ex:predicate skos:prefLabel ; ]
>>>>>>> .
>>>>>>>
>>>>>>> This (common) case above could be turned into a template
>>>>>>> sh:PropertyScope:
>>>>>>>
>>>>>>> ex:MyShape sh:scope [ a sh:PropertyScope ; sh:predicate
>>>>>>> skos:prefLabel . ] ; sh:constraint [ a
>>>>>>> ex:UniqueLanguageConstraint ; ex:predicate skos:prefLabel ; ]
>>>>>>> .
>>>>>>>
>>>>>>> and we could provide a small collection of frequently needed
>>>>>>> scopes, e.g.
>>>>>>>
>>>>>>> - all nodes in a graph - all subjects - all nodes with any
>>>>>>> rdf:type - all IRI nodes from a given namespace
>>>>>>>
>>>>>>> Systems that don't speak SPARQL would rely on the hard-coded
>>>>>>> IRIs from the core vocabulary, such as sh:PropertyScope.
>>>>>>>
>>>>>>> We could now also formally define the scope behind
>>>>>>> sh:scopeClass (and sh:nodeShape):
>>>>>>>
>>>>>>> sh:ClassScope a sh:TemplateScope ; sh:argument [ sh:predicate
>>>>>>> sh:class ; # Becomes ?class sh:valueType rdfs:Class ; ] ;
>>>>>>> sh:sparql """ SELECT ?this WHERE { ?type rdfs:subClassOf*
>>>>>>> ?class . ?this a ?type . } """ .
>>>>>>>
>>>>>>> In addition to these scopes, I suggest we turn sh:scopeShape
>>>>>>> into sh:filterShape, and use these filters as pre-conditions
>>>>>>> that are evaluated for a given set of focus nodes. The
>>>>>>> workflow then becomes:
>>>>>>>
>>>>>>> - sh:scope produces bindings for ?this - sh:filterShape
>>>>>>> filters out the values of ?this that do not match the given
>>>>>>> shape - the actual constraints are evaluated
>>>>>>>
>>>>>>> I believe this design provides the flexibility of a generic
>>>>>>> scoping mechanism (as suggested in Peter's design) without
>>>>>>> getting into the complexity of having to analyze SPARQL syntax
>>>>>>> or rely on hacks with rdfs:Resource, while having a
>>>>>>> user-friendly syntax. The fact that we separate sh:Scope from
>>>>>>> sh:Shape means that we can enforce different, explicit
>>>>>>> semantics on scopes. For example we could allow a sh:Scope to
>>>>>>> encapsulate another SPARQL query that tests whether a given
>>>>>>> ?this is in scope, i.e. the inverse direction of the SELECT
>>>>>>> query, to optimize performance.
>>>>>>>
>>>>>>> Thanks, Holger
>>>>>>>
>>>>>>>
>>> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2
>>>
>>> iQEcBAEBCAAGBQJVcZDFAAoJECjN6+QThfjz5JEH/iCrAv0qYg3HnqZjxqIP4e0C
>>> cTJVrhSU3td+cKdRqe7gomMT8iQ+wwv4lAzmIuVLkePX1gpuPIMegOo39Hrgo1/7
>>> Xilum+XX9tfW81YOWBKyeoX+VLcG8VVVtCt8B6v997NMLJZQz9CduKMV0Au+ZG/r
>>> Ljdjn8aqOcE9qTXehXLJ71PSRBoMUw26bo7FAwke4VAhNrARSxO3x89xe1Aw+g96
>>> dydZIgU65Ega8NhEAjWz3RLjJXNLfF1TZ8Ti9nNzlb4H2PeReIRiTsRPKVvXdFXo
>>> 9sXFF29LtWJs5QlJ5LSqJS8AMZOJK9uNACVm14DL5HCP//vx/iU734/A6d/xYNw= =Pa8K
>>>   -----END PGP SIGNATURE-----
>>
>
> On 06/08/2015 03:15 AM, Holger Knublauch wrote:
>> Hi Peter, could we try to take baby steps towards a resolution here. My
>> first question: your proposal has sh:sparqlScope - a query fragment that
>> delivers bindings for ?this. Do you agree that it makes sense to
>> generalize this to also allow templates here? This would allow us and
>> others to introduce something like sh:PropertyScope or
>> sh:AllSubjectsScope as high-level language terms without forcing users
>> to repeat the underlying SPARQL query over and over again. It would also
>> cater for other languages than SPARQL, if we decide to allow other
>> extension languages.
>>
>> Thanks, Holger
>>
>>
>> On 6/5/15 10:06 PM, Peter F. Patel-Schneider wrote: So this ends up with
>> scopes, filters, and constraints.  It requires that constraints do
>> double duty, as both constraints and filters.
>>
>> I still think that it is cleaner for shapes to have a scope and one or
>> more constraints only, and to have constraints be used in both places. It
>> eliminates a construct without eliminating any expressive power.
>>
>> As far as binding goes there are several reasonable solutions, one of
>> which is in essence automatically adding in a "universal" binding when
>> required. I think that using constraints as filters is going to have the
>> same issue anyway.
>>
>>
>>
>> Using constraints as scopes can be done without requiring double
>> expansion in templates.   For the example you mention below, my SPARQL
>> expansion for hasValue on rdf:type to http:/example.org/Person could be
>> used as the scope. It is not formulated in the opposite direction.
>>
>>
>> peter
>>
>>
>>
>> On 06/04/2015 04:29 PM, Holger Knublauch wrote:
>>>>> On 6/5/2015 8:54, Peter F. Patel-Schneider wrote: There were
>>>>> already separate scopes for individual-based scoping and
>>>>> class-based scoping.
>>>>>
>>>>>> Yes, my proposal is to keep sh:scopeClass and sh:nodeShape as
>>>>>> syntactic sugar for the frequently needed cases that they cover.
>>>>> Do you mean that there should now be a new kind of template for
>>>>> scopes, and new special scopes, all separate from constraints?
>>>>>
>>>>>> Yes, because scopes and shapes are very different concepts.
>>>>>> Scopes produce focus nodes, while constraints validate given
>>>>>> focus nodes.
>>>>> Constraints are already available, and can do double duty as
>>>>> scopes. Why not use them for determining the scope of a shape
>>>>> particularly as you then actually do use them for this purpose,
>>>>> but as filters.  I don't see what the point is of adding all this
>>>>> extra stuff.
>>>>>
>>>>>> Because they cannot always do double duty, as we had discussed
>>>>>> here at length. This is due to the way that they are
>>>>>> implemented. A constraint produces violation instances, but what
>>>>>> we need are focus nodes. In other words, constraints look for the
>>>>>> counter examples, while we would need the opposite direction to
>>>>>> find all nodes that actually fit. I am surprised about your
>>>>>> feedback, because your own proposal had exactly the same concept,
>>>>>> in form of sh:sparqlScope. In your own example, you use it to
>>>>>> return all instance of ex:Person: [ rdf:type sh:Constraint ;
>>>>>> sh:severity sh:fatalError ; sh:report "SELECT ?person" ;
>>>>>> sh:sparqlScope "?person rdf:type <http://example.org/Person>" ;
>>>>>> sh:sparqlShape """FILTER NOT EXISTS { ?person ex:offspring
>>>>>> ?offspring . FILTER NOT EXISTS { ?offspring rdf:type ex:Person .
>>>>>> } }""" ] . If this scope were a constraint, then it would be
>>>>>> formulated in the opposite direction "report an error if this is
>>>>>> not an instance of ex:Person". All I have done is generalize your
>>>>>> approach to allow sparqlScope to also be a template, and I have
>>>>>> moved your sh:shapeScope into sh:filterShape. This solves the
>>>>>> problem with your approach, that some constraints simply do not
>>>>>> bind ?this. Your work-around was to inject some magic to bind
>>>>>> ?this with all instances of rdfs:Resource, so but even this hack
>>>>>> now can have an official solution: sh:ShapeScope a
>>>>>> sh:ScopeTemplate sh:argument [ sh:predicate sh:shape ; # becomes
>>>>>> ?shape in the query sh:valueType sh:Shape ; rdfs:comment "The
>>>>>> shape that all focus nodes must have" ] ; sh:sparql """ SELECT
>>>>>> ?this WHERE { ?this a rdfs:Resource . FILTER sh:hasShape(?this,
>>>>>> ?shape) } """ . And we side-step the question whether ?this
>>>>>> should by default be all subjects, all nodes, all instances, etc.
>>>>>> We just define a generic mechanism and let the model do the rest.
>>>>>> Anyone can add their own scoping template. As a bonus we don't
>>>>>> have to look into complex SPARQL query analysis to find out
>>>>>> whether a query is binding ?this and similar unnecessary
>>>>>> complexity that few users will understand. Hope this makes sense,
>>>>>> I can elaborate further. Holger
>>>>>
>>>>> peter
>>>>>
>>>>>
>>>>> On 06/03/2015 04:16 PM, Holger Knublauch wrote:
>>>>>>>> I thought more about the issue of generic scopes and filters
>>>>>>>> and have come up with a variation of Peter's design.
>>>>>>>> Assuming we define
>>>>>>>>
>>>>>>>> - Scope: takes a graph as input and produces bindings for
>>>>>>>> the focus node (?this)
>>>>>>>>
>>>>>>>> Graph -> focus nodes
>>>>>>>>
>>>>>>>> - Constraint: that takes a focus node as input and produces
>>>>>>>> (violation) results:
>>>>>>>>
>>>>>>>> focus nodes -> results
>>>>>>>>
>>>>>>>> I think we should make Scopes an explicit concept in SHACL's
>>>>>>>> RDF vocabulary, similar to how shapes are defined. There
>>>>>>>> would be the following class hierarchy:
>>>>>>>>
>>>>>>>> sh:Scope sh:NativeScope sh:TemplateScope
>>>>>>>>
>>>>>>>> And native scopes can have sh:sparql (or a JS body etc).
>>>>>>>> Example
>>>>>>>>
>>>>>>>> # Applies to all subjects that have a skos:prefLabel
>>>>>>>> ex:MyShape sh:scope [ a sh:NativeScope ; # Optional rdf:type
>>>>>>>> triple sh:sparql """ SELECT DISTINCT ?this WHERE { ?this
>>>>>>>> skos:prefLabel ?any } """ ] ; sh:constraint [ a
>>>>>>>> ex:UniqueLanguageConstraint ; ex:predicate skos:prefLabel ;
>>>>>>>> ] .
>>>>>>>>
>>>>>>>> This (common) case above could be turned into a template
>>>>>>>> sh:PropertyScope:
>>>>>>>>
>>>>>>>> ex:MyShape sh:scope [ a sh:PropertyScope ; sh:predicate
>>>>>>>> skos:prefLabel . ] ; sh:constraint [ a
>>>>>>>> ex:UniqueLanguageConstraint ; ex:predicate skos:prefLabel ;
>>>>>>>> ] .
>>>>>>>>
>>>>>>>> and we could provide a small collection of frequently needed
>>>>>>>>   scopes, e.g.
>>>>>>>>
>>>>>>>> - all nodes in a graph - all subjects - all nodes with any
>>>>>>>> rdf:type - all IRI nodes from a given namespace
>>>>>>>>
>>>>>>>> Systems that don't speak SPARQL would rely on the hard-coded
>>>>>>>> IRIs from the core vocabulary, such as sh:PropertyScope.
>>>>>>>>
>>>>>>>> We could now also formally define the scope behind
>>>>>>>> sh:scopeClass (and sh:nodeShape):
>>>>>>>>
>>>>>>>> sh:ClassScope a sh:TemplateScope ; sh:argument [ sh:predicate
>>>>>>>> sh:class ; # Becomes ?class sh:valueType rdfs:Class ; ] ;
>>>>>>>> sh:sparql """ SELECT ?this WHERE { ?type rdfs:subClassOf*
>>>>>>>> ?class . ?this a ?type . } """ .
>>>>>>>>
>>>>>>>> In addition to these scopes, I suggest we turn sh:scopeShape
>>>>>>>> into sh:filterShape, and use these filters as pre-conditions
>>>>>>>> that are evaluated for a given set of focus nodes. The
>>>>>>>> workflow then becomes:
>>>>>>>>
>>>>>>>> - sh:scope produces bindings for ?this - sh:filterShape
>>>>>>>> filters out the values of ?this that do not match the given
>>>>>>>> shape - the actual constraints are evaluated
>>>>>>>>
>>>>>>>> I believe this design provides the flexibility of a generic
>>>>>>>> scoping mechanism (as suggested in Peter's design) without
>>>>>>>> getting into the complexity of having to analyze SPARQL
>>>>>>>> syntax or rely on hacks with rdfs:Resource, while having a
>>>>>>>> user-friendly syntax. The fact that we separate sh:Scope
>>>>>>>> from sh:Shape means that we can enforce different, explicit
>>>>>>>> semantics on scopes. For example we could allow a sh:Scope
>>>>>>>> to encapsulate another SPARQL query that tests whether a
>>>>>>>> given ?this is in scope, i.e. the inverse direction of the
>>>>>>>> SELECT query, to optimize performance.
>>>>>>>>
>>>>>>>> Thanks, Holger
>>>>>>>>
>>>>>>>>
>>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v2
>
> iQEcBAEBCAAGBQJVdg3gAAoJECjN6+QThfjz0woH/1ZFrFzUkkEXuzuELqY07U7y
> sJgbfmtOxDqJ0jboJKiKqG9Y6Lx3Egn2T3mxsStruLzQbi1T0DsRAWEdTSRO6/Yd
> /S/+gjOEXFuw0O/Hjqj2Y6QJqt4qrlOJvW4uuG2nEYjt5LBdM83lL5Hf5n0CtAQn
> MWZeJtpQTvwynRDSMgDHQmuuVmAAGKpIIfQ3daL20pGOXe4HI0dEmnfv4/Rvjbq6
> aBmp90pBKKaR+AQp4xuBRwehEPB4TQ+GAM+ml2zUPXii9dc2DkzxbpuJoS2HTZSJ
> okmQ/qmov11hV8DPbaRlpqBizQY7XiERQmQOXTcYw72+4+SLqeCp6e3Yx3aNZhY=
> =I4Ic
> -----END PGP SIGNATURE-----

Received on Tuesday, 9 June 2015 09:19:21 UTC