vaticle-typedbvaticle-typeql

How to define a transitive relation in graql


my model consists of organizations that have projects and the projects have buckets. The buckets can be shared to other projects in the same organization. I defined a rule for project sharing which means that two projects are in this relation when first is sharing a bucket with the other.

    define

    organization sub entity,
        plays organizationRole,
        key identifier;

    project sub entity,
        plays projectRole,
        plays projectSourceRole, 
        plays projectTargetRole,
        plays transitiveProjectSourceRole,
        plays transitiveProjectTargetRole,
        key identifier;

    bucket sub entity,
        plays bucketRole,
        plays sharedBucketSourceRole,
        plays sharedBucketTargetRole,
        key identifier;


    organizationToProject sub relation,
        relates organizationRole,
        relates projectRole;

    projectToBucket sub relation,
        relates projectRole,
        relates bucketRole;

    sharedBucket sub relation,
        relates sharedBucketSourceRole,
        relates sharedBucketTargetRole;

    projectSharing sub relation,
        relates projectSourceRole,
        relates projectTargetRole;

    project-sharing sub rule, 
      when { 
        (projectRole: $ps, bucketRole: $bs) isa projectToBucket; 
        (projectRole: $pt, bucketRole: $bt) isa projectToBucket;
        (sharedBucketSourceRole: $bs, sharedBucketTargetRole: $bt) isa sharedBucket;
        $ps != $pt;
      }, then { 
        (projectSourceRole: $ps, projectTargetRole: $pt) isa projectSharing; 
      };

It works fine. (see enter image description here)

But I want to define a rule for transitive relation (according to some ancestry example I found in the docs) so I added to the schema:

    transitiveProjectSharing sub relation,
        relates transitiveProjectSourceRole,
        relates transitiveProjectTargetRole;

    transitive-project-sharing sub rule,
      when {
        (projectSourceRole: $a, projectTargetRole: $b) isa projectSharing;
        (projectSourceRole: $b, projectTargetRole: $c) isa projectSharing; 
      }, then {
        (transitiveProjectSourceRole: $a, transitiveProjectTargetRole: $c) isa transitiveProjectSharing;
      };

It finds nothing (but there are several transitive ones, see enter image description here)

Would anyone have a suggestion where is the mistake?


Solution

  • I've got a hint from Grakn.ai Slack. The transitivity should be defined on the projectSharing role itself, additional transitiveProjectSharing is not necessary. So the definition should be:

    transitive-project-sharing sub rule,
      when {
        (projectSourceRole: $a, projectTargetRole: $b) isa projectSharing;
        (projectSourceRole: $b, projectTargetRole: $c) isa projectSharing; 
      }, then {
        (projectSourceRole: $a, projectTargetRole: $c) isa projectSharing; 
      };
    
    

    and the query works well: enter image description here