Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On a odrl:refinement over an Action / Asset Collection / Party Collection #64

Open
joshcornejo opened this issue Oct 8, 2024 · 16 comments

Comments

@joshcornejo
Copy link
Collaborator

In the examples (14), in JSON we have the following

       "action": [{
          "rdf:value": { "@id": "odrl:print" },
          "refinement": [{
             "leftOperand": "resolution",
             "operator": "lteq",
             "rightOperand": { "@value": "1200", "@type": "xsd:integer" },
             "unit": "http://dbpedia.org/resource/Dots_per_inch"
          }]
      }]

When transformed to TTL:

              odrl:action ex:URI_23244A;
ex:URI_23244A a odrl:Action;                      // <== this node is not an Action
              rdf:value odrl:print;
              odrl:refinement ex:URI_23245A.
ex:URI_23245A a odrl:Constraint;
              odrl:leftOperand odrl:resolution;
              odrl:operator odrl:lteq;
              odrl:unit "http://dbpedia.org/resource/Dots_per_inch"^^xsd:string;
              odrl:rightOperandReference ex:URI_23246R. // not included

The class of md:URI_23244A surfaces (implicit in JSON, hidden under the opening "[{" ).

When the example is swapped from an odrl:action to either odrl:target or odrl:function, it becomes confusing:

// ----------------------------------------------------------------
              odrl:target ex:URI_23244A;
ex:URI_23244A a odrl:AssetCollection;            // <== this is not an AssetCollection
              rdf:value ex:SomeAssetCollection;  // <== this is the collection
              odrl:refinement ex:URI_23245A.
// ----------------------------------------------------------------
              odrl:function ex:URI_23244A;
ex:URI_23244A a odrl:PartyCollection;            // <== this is not an PartyCollection
              rdf:value ex:SomePartyCollection;  // <== this is the collection
              odrl:refinement ex:URI_23245A.
// ----------------------------------------------------------------

From the diagram, the issue is:

Screenshot 2024-10-08 at 09 06 23

@riannella
Copy link
Collaborator

When you transform Example 14 to turtle, you would get:

<http://example.com/policy:6161>  a odrl:Offer ;
  odrl:profile <http://example.com/odrl:profile:10> ;
   odrl:assigner <http://example.com/org:616> ;
   odrl:target <http://example.com/document:1234> ;
  odrl:permission [
    odrl:action [
      rdf:value odrl:print ;
      odrl:refinement [
        odrl:leftOperand odrl:resolution ;
        odrl:operator odrl:lteq ;
        odrl:rightOperand "1200"^^xsd:integer ;
        odrl:unit "http://dbpedia.org/resource/Dots_per_inch"^^xsd:string
        ]
      ] ;
  ] .

@joshcornejo
Copy link
Collaborator Author

joshcornejo commented Oct 9, 2024

That's the compressed syntax with anonymous nodes and leaves the node rdf:Class hidden (not clear if i had multiple nodes pointing at the same refinement for example), can we use the extended syntax (that's what comes out of the library, and that will tell me what is that I need to add when there is a refinement)

@vroddon
Copy link
Collaborator

vroddon commented Oct 26, 2024

odrl:print is an instance of the class odrl:Action.

If you need the object of an RDF triple referring to "printing", using that URI ("odrl:print") is enough and simple.
If you need to say more things about that fact of printing, we need another RDF resource, subject of other triples that refine it. Indeed, the first and foremost of such triples is the fact that we still referring to the printing action (odrl:print).
We do this by means of the rdf:value, as illustrated in the example above.
Indeed, in Turtle or in JSON-LD we can have such a resource fully anonymous, if you like it.

This is succintly explained in Section 2.5.4 of the ODRL model. Is the 'note' in that section enough (and the examples above in that section)? Or do you think it needs further clarification?

@joshcornejo
Copy link
Collaborator Author

The actions are a bit of a red herring. I am not talking about the property that points at the action, I am concerned about the "wrapper" class for the refinements. I think it needs further clarification, ideally in "fully qualified domains" as that is what the libraries need to add triples (even if you can then output "succinct").

As I explained above (copy/paste again), I have a refinement for an AssetCollection or a PartyCollection, odrl:target or odrl:function are not "pointing at " an AssetCollection or PartyCollection, they are "pointing at something else" and that "something else" now has an "rdf:Value".

// ----------------------------------------------------------------
              odrl:target ex:URI_23244A;         // <== the diagram says this is "pointing at an AssetCollection"
ex:URI_23244A a odrl:AssetCollection;            // <== this is not an AssetCollection
              rdf:value ex:SomeAssetCollection;  // <== this is the collection
              odrl:refinement ex:URI_23245A.
// ----------------------------------------------------------------
              odrl:function ex:URI_23249A;       // <== the diagram says this is "pointing at a PartyCollection"
ex:URI_23249A a odrl:PartyCollection;            // <== this is not an PartyCollection
              rdf:value ex:SomePartyCollection;  // <== this is the collection
              odrl:refinement ex:URI_23245A.
// ----------------------------------------------------------------

In other words: If I was building the SHACL for the classes that are the target for odrl:refinement - they are "not currently defined".

@vroddon
Copy link
Collaborator

vroddon commented Oct 26, 2024

The class you are looking for is odrl:Action (if the refinement is of an Action).
Please note that the odrl:action property, has defined as rdfs:range the Action class. This means, according to the RDFS semantics, that "any object in a triple where odrl:action is the property, has class odrl:Action".
We can explicitly declare that, if you like, but knowing that it can be inferred, it can be omitted.

In the examples you post, from the odrl:target property, we can infer that ex:URI_23244A is an odrl:Asset (or any of its subclasses, as odrl:AssetCollection). Therefore, in your examples, you do well by saying that ex:URI_23244A is a odrl:AssetCollection: in this case there was an ambiguity.

@riannella
Copy link
Collaborator

I think the rdf:value properties should be odrl:source properties.

@joshcornejo
Copy link
Collaborator Author

Forget the action example ...

@riannella @vroddon I believe we might be talking about different things, I will elaborate the example further with a couple of diagrams.

Somewhere, someone defines an asset collection:

md:some_catalog terms:accessRights odrl:distribute,
                                    odrl:use;
                 terms:accrualPeriodicity prov:freq-N;
                 terms:created "2024-08-22T14:08:23.0000000Z"^^xsd:dateTime;
                 terms:description "this is an example of a catalog"@en;
                 a odrl:AssetCollection,
                   fibo-fnd-acc-aeq:FinancialAsset,
                   dcat:Catalog;
                 owl:versionInfo "1.0"@en;
                 prov:generatedBy "[email protected]"^^xsd:anyURI;
                 prov:version "1.0"@en;
                 dprod:informationSensitivityClassification md:public.

Now we move to the policy creation under ODRL:

  • According to the diagram odrl:target should point at an odrl:AssetCollection (or action or partycollection).
  • My policy user has two rules: a permission and a prohibition, the permission refines md:some_catalog, the prohibition doesn't.

The permission's target:

       odrl:target ex:URI_23244A;         // <== this is pointing at a **REFINEMENT** to an AssetCollection

The prohibition's target:

       odrl:target md:some_catalog;         // <== this is "pointing" at an AssetCollection

So ex:URI_23244A is not an AssetCollection, and the refinement should not be part of the asset's triples, because the ex:URI_23245A is a property of the refinement in the permission and not a property of the asset itself.

ex:URI_23244A a odrl:AssetCollection;            // <== this is not an AssetCollection
              rdf:value md:some_catalog;         // <== this is the collection
              odrl:refinement ex:URI_23245A.

refinement

I would argue that odrl:target md:some_catalog; is an abstraction that is a shortcut and "hiding" an intermediate node because it is not required, but it could also be represented:

another

@riannella
Copy link
Collaborator

When you say:
odrl:target ex:URI_23244A; // <== this is pointing at a **REFINEMENT** to an AssetCollection
How can this be?
The range of target is Asset ?

@joshcornejo
Copy link
Collaborator Author

The target might be defined in writing as an odrl:AssetCollection, but when you have 2 rules pointing at the same asset, with different requirements (one refinement, one not) and you lay it in a graph (as above) that the range comes into question.

I aim to show in the diagrams above: that it isn't in the range of an asset in the graph. There is a node that in a "single rule JSON" can look like it is implicit, but not in FQN RDF with multiple rules and different refinements on an element (in this example an AssetCollection.

To start, I hope we agree that ex:constraints is not a property of the odrl:AssetCollection, that is a requirement specified by a rule ex:some_permission within a policy, other rules within the same policy (ex:some_prohibition) could have different requirements (or not) and address the same asset.

When you output the RDF that includes an asset and a policy, in the example above ex:some_catalog doesn't have ex:constraints as properties (otherwise ex:some_prohibition should also consider them?)

As per the example above, this is a DCAT catalog:

ex:some_catalog terms:accessRights odrl:distribute,
                                    odrl:use;
                 terms:accrualPeriodicity prov:freq-N;
                 terms:created "2024-08-22T14:08:23.0000000Z"^^xsd:dateTime;
                 terms:description "this is an example of a catalog"@en;
                 a odrl:AssetCollection,
                   dcat:Catalog;
                 owl:versionInfo "1.0"@en;
                 prov:generatedBy "[email protected]"^^xsd:anyURI;
                 prov:version "1.0"@en;
                 dprod:informationSensitivityClassification md:public.

And we can create a policy:

ex:policy   terms:created "2024-10-05T06:41:47.0000000Z"^^xsd:dateTime;
            terms:creator "some UUID"^^xsd:anyURI;
            terms:description "Example of an Offer"@en;
            terms:valid md:uri:225b96258645:23241I;
            a odrl:Offer;
            owl:versionInfo "0.1"@en;
            odrl:conflict odrl:prohibit;
            odrl:permission ex:demo_permission;
            odrl:prohibition ex:demo_prohibition;
            prov:version "0.1"@en.

The prohibition does look like the target is just the ex:some_catalog which is an odrl:AssetCollection:

ex:demo_prohibition a odrl:Prohibition;
                    odrl:action odrl:distribute;
                    odrl:target ex:some_catalog.

But you can't "attach" the refinement to ex:some_catalog for the permission:

ex:demo_permission a odrl:Permission;
                   odrl:action odrl:play;
                   odrl:target ex:some_catalog.  // the refinement shouldn't be a 'property' of the asset
                                                 // otherwise it will be triggered by other rules

It needs a class that binds the semantics "for this rule, the target has this refinement":

ex:demo_permission a odrl:Permission;
                   odrl:action odrl:play;
                   odrl:target ex:URI_23244A;

But ex:URI_23244A is not an asset ... is the binder for the permission that says "this asset has this refinement"

ex:URI_23244A a odrl:AssetCollection;            // <== this is not an AssetCollection, nor is the target
              rdf:value ex:some_catalog;         // <== this is the target AssetCollection
              odrl:refinement ex:some_constraints.

IMHO: odrl:target / odrl:function / odrl:action should have more detailed definitions for range.

@riannella
Copy link
Collaborator

A refinement is a type of odrl:Constraint (or odrl:LogicalConstraint)

So you can create an instance of the refinement, then only refer to it in the Permission.

Like:

ex:someCatalog rdf:type odrl:Asset, odrl:AssetCollection .

ex:policy01 rdf:type  odrl:Offer ;
            odrl:permission ex:perm01 ;
            odrl:prohibition ex:prohib01 .

ex:perm01 rdf:type odrl:Permission ;
          odrl:action odrl:play ;
          odrl:target [ rdf:type odrl:AssetCollection ;
                        odrl:source ex:someCatalog ;
                        odrl:refinement ex:refine01 . ] .

ex:prohib01 rdf:type odrl:Prohibition ;
            odrl:action odrl:distribute ;
            odrl:target ex:someCatalog .


ex:refine01 rdf:type  odrl:Constraint ;
            odrl:leftOperand odrl:resolution ;
            odrl:operator odrl:lteq ;
            odrl:rightOperand [ rdf:type xsd:integer ; rdf:value "1200" ] .

@joshcornejo
Copy link
Collaborator Author

When you say "you can" - I can't, as I explained yesterday, the library is asking for a node "to attach" the refinement.

A text file like the one you produced above looks like it works, but in a graph it doesn't make sense.

ex:perm01 rdf:type odrl:Permission ;
          odrl:action odrl:play ;
          odrl:target [ rdf:type odrl:AssetCollection ;
                        odrl:source ex:someCatalog ;
                        odrl:refinement ex:refine01 . ] .

As per the graph below odrl:target is implying that the node "????" is an odrl:AssetCollection?

odrl_refinement

When I add another rule with a the same topology (target-refinement) over the same asset, but different refinement:

ex:prohib01 rdf:type odrl:Prohibition ;
            odrl:action odrl:distribute ;
            odrl:target ex:someCatalog .

ex:perm02 rdf:type odrl:Permission ;
          odrl:action odrl:aggregate ;
          odrl:target [ rdf:type odrl:AssetCollection ;
                        odrl:source ex:someCatalog ;
                        odrl:refinement ex:refine02. ] .

refinement2

I would be interested in seeing what result a SPARQL query returns on how many odrl:AssetCollection elements now exist.

IMHO - these look very confusing as it appear to attach properties ("odrl:refinement") to the AssetCollection.

@riannella
Copy link
Collaborator

Seems to work fine when I load into GraphDB
Screenshot 2024-12-04 at 17 34 30

@riannella
Copy link
Collaborator

And the SPARQL
Screenshot 2024-12-04 at 17 28 52

@riannella
Copy link
Collaborator

ex:someCatalog rdf:type odrl:Asset, odrl:AssetCollection .

ex:policy01 rdf:type  odrl:Offer ;
            rdfs:label "Policy 01" ;
            odrl:permission ex:perm01, ex:perm02 ;
            odrl:prohibition ex:prohib01 .

ex:perm01 rdf:type odrl:Permission ;
          rdfs:label "Permission 01" ;
          odrl:action odrl:play ;
          odrl:target ex:perm01-target .

ex:perm01-target rdf:type odrl:AssetCollection ;
           rdfs:label "Perm01 Target" ;
                 odrl:source ex:someCatalog ;
                odrl:refinement ex:refine01 .

ex:refine01 rdf:type  odrl:Constraint ;
          rdfs:label "Refinement 01" ;
            odrl:leftOperand odrl:resolution ;
            odrl:operator odrl:lteq ;
            odrl:rightOperand ex:refine01-rightOp .

ex:refine01-rightOp rdf:type xsd:integer ;
             rdfs:label "Refine01 RightOp" ;
            rdf:value "1200"  .

ex:perm02 rdf:type odrl:Permission ;
          rdfs:label "Permission 02" ;
          odrl:action odrl:play ;
          odrl:target ex:perm02-target .

ex:perm02-target rdf:type odrl:AssetCollection ;
           rdfs:label "Perm02 Target" ;
                 odrl:source ex:someCatalog ;
                odrl:refinement ex:refine02 .

ex:refine02 rdf:type  odrl:Constraint ;
          rdfs:label "Refinement 02" ;
            odrl:leftOperand odrl:resolution ;
            odrl:operator odrl:gteq ;
            odrl:rightOperand ex:refine02-rightOp .

ex:refine02-rightOp rdf:type xsd:integer ;
             rdfs:label "Refine02 RightOp" ;
            rdf:value "32000"  .

ex:prohib01 rdf:type odrl:Prohibition ;
            odrl:action odrl:distribute ;
            odrl:target ex:someCatalog .

@joshcornejo
Copy link
Collaborator Author

This just showed exactly the problem where I started in March. Are those ex:perm-target asset collections (are they managed in the asset section?), Do people need to know about the existence of policies to create a clean query? it doesn't seem to flow as the ODRL diagram (none of those -target point at a policy).

Screenshot 2024-12-04 at 07 48 32

The query should return 1 asset/assetCollection - ex:someCatalog, but it has returned 3:

ex:someCatalog rdf:type odrl:Asset, odrl:AssetCollection .

ex:perm01-target rdf:type odrl:AssetCollection ;
           rdfs:label "Perm01 Target" ;
                 odrl:source ex:someCatalog ;
                odrl:refinement ex:refine01 .

ex:perm02-target rdf:type odrl:AssetCollection ;
           rdfs:label "Perm02 Target" ;
                 odrl:source ex:someCatalog ;
                odrl:refinement ex:refine02 .

It might appear as a good binding from an ODRL perspective.

But from the asset manager's perspective how is it justified semantically?, the -target nodes are now unmanaged, redundant and somewhat unlinked to the ex:someCatalog (responsibility principles would dictate asset creations are managed by the "asset manager role", not the "policy manager role") - does the 'ex:someCatalog need to have a property that says ex:surrogate-target to keep track to those for completeness? I don't think so.

Further, when you generate the JSON-LD (because this is what is used by most API), parsing is cluttered - there are 3 entries for odrl:AssetCollection, need to figure out which is the actual asset. Now it also is waste of code, and waste of execution time.

If the purpose of making it a -Collection is to represent that the "output" of the refinement is still -Collection, that is unnecessary (just like SPARQL can output anything, a refinement should output anything) - the outcome of the query is when applying the refinement, the result shouldn't be an empty set (practically: true/false), not an actual list.

This is about end-to-end lifecycle and IMHO, still stands: it is not elegant and will confuse developers just as it has done to me so far.

@vroddon
Copy link
Collaborator

vroddon commented Dec 20, 2024

I fully understand @joshcornejo's point, there is something "logically" wrong about this SPARQL query returning three instances of AssetCollection, when only one has real existence. Either the factuality is marked, or a different model is seeked. I do not see a solution compatible with the current ODRL spec. Therefore, solving this problem would be a major change to the spec --discussion should be elevated to ODRL plennary meetings. More info in the wiki

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants