Как я могу определить симметричные отношения в Graql

Я пытаюсь смоделировать современный набор данных ( http://www.tinkerpop.com/docs/3.0.0.M7/images/tinkerpop-modern.png) в Graql. Марко знает, Вадас, а Вадас знает Марко - для целей этого примера я предполагаю, что они друзья.

Так я могу это сделать?

    insert friendship isa relation-type;
    insert friend isa role-type;
    insert friendship has-role friend, has-role friend;

Все примеры, которые я видел до сих пор, имеют две разные роли в отношениях (например, учитель / ученик).

2 ответа

Роли должны быть разными, поэтому вы не можете иметь две friend роли в одном отношении.

Если отношение, которое вы описываете, является симметричным, вы должны вместо этого ввести две роли friend1 а также friend2, Если вы хотите, они оба могут быть ako friend,

Учитывая набор данных, который вы используете, может быть, лучше не описывать это как симметричные отношения, а вместо этого использовать knows отношения, где одна роль является knower а другая роль known-about,

Вы можете использовать тот факт, что любая роль может повторяться в экземпляре отношения:

friendship sub relation,
  relates friend;

name sub attribute,
  datatype string;

person sub entity,
  has name,
  plays friend;

Тогда ты можешь сказать

insert $x isa Person, has name "X";
insert $y isa Person, has name "Y";
match
  $x isa Person, has name "X";
  $y isa Person, has name "Y";
insert $xy (friend: $x, friend: $y) isa friendship;

Как отметил Феликс Чепмен, типы ролей уникальны, поэтому истинное симметричное отношение невозможно.

Есть несколько способов обойти это; говорят, что вы определили свои отношения как

insert
friendship isa relation-type
  has-role friend1
  has-role friend2;

Первая возможность заключается в использовании ako и абстрактные роли:

friend isa role-type is abstract;
friend1 ako friend;
friend2 ako friend;

person isa entity-type plays-role friend;

Вторая возможность заключается в использовании правил вывода:

SymmetricFriendship isa inference-rule,
  lhs {match (friend1 $x, friend2 $y) isa friendship;
       select $x, $y},
  rhs {match (friend1 $y, friend2 $x} isa friendship;};

Второй способ делает отношение дружбы истинно симметричным отношением с математической точки зрения, но, учитывая синтаксис соответствия Graql и по соображениям производительности, редко возникает необходимость явно сделать отношение симметричным, поэтому я лично предпочитаю первый способ.

Вы можете сделать что-то симметричное, добавив entity который моделирует группу друзей:

friendship sub relation,
  relates friend,
  relates friend-group;

person sub entity,
  plays friend;

group sub entity,
  plays friend-group;

Это действительно похоже на лачугу. ВfriendshipОтношение эффективно просто выражает отношение подмножества. я использовалgroup вместо того pair потому что сейчас friendship больше не является двоичным, так как я не знаю, как ограничить количество friendс в friend-group. Более того, одни и те же два друга могут быть частью несколькихfriendshipс.

Graql как язык моделирования был бы более мощным, если бы он позволял задавать вариативные отношения, например, используя диапазоны количества ролевых игроков для каждой роли. Это также охватывает этот вариант использования:

friendship sub relation,
  relates 2 friend;
Другие вопросы по тегам