Как я могу определить симметричные отношения в 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;