如何在 graql 中定义传递关系

How to define a transitive relation in graql

我的模型由有项目的组织组成,项目有桶。存储桶可以共享给同一组织中的其他项目。我为项目共享定义了一个规则,这意味着两个项目在第一个与另一个共享一个桶时处于这种关系。

    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; 
      };

它工作正常。 (参见

但是我想为传递关系定义一个规则(根据我在文档中找到的一些祖先示例)所以我添加到架构中:

    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;
      };

它什么也没找到(但是有几个传递的,见

谁能告诉我错误在哪里?

我从 Grakn.ai Slack 得到了提示。传递性应该在 projectSharing 角色本身上定义,不需要额外的 transitiveProjectSharing。所以定义应该是:

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; 
  };

并且查询运行良好:

作为对您非常优雅的答案的轻微改进(谢谢!!),您还可以使用子类型来区分显式关系和推断关系:

indirectProjectSharing sub projectSharing;

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

由于 indirectProjectSharingprojectSharing 的子类型,规则的条件将匹配这两种关系,您可以根据用例在自己的查询中引用任一类型。