Andrew Bracker
Andrew Bracker

Reputation: 55

How can I define a symmetric relationship in Graql

I'm trying to model the Modern dataset (http://www.tinkerpop.com/docs/3.0.0.M7/images/tinkerpop-modern.png) in Graql. Marko knows Vadas and Vadas knows Marko - for the purposes of this example, I'm assuming that they are friends.

So can I do this?

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

All the examples I've seen so far, have two different roles on a relationship (e.g. teacher/student).

Upvotes: 2

Views: 94

Answers (4)

equaeghe
equaeghe

Reputation: 1784

You can use the fact that any role can be repeated in a relationship instance:

friendship sub relation,
  relates friend;

name sub attribute,
  datatype string;

person sub entity,
  has name,
  plays friend;

Then you can say

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;

Upvotes: 0

equaeghe
equaeghe

Reputation: 1784

You can do something symmetric by adding an entity that models a group of friends:

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

person sub entity,
  plays friend;

group sub entity,
  plays friend-group;

This does feel like a kludge. The friendship relation effectively just expresses the subset relationship. I have used group instead of pair because now friendship is not binary any more, as I do not know how to restrict the number of friends in a friend-group. Moreover, the same two friends can be part of multiple friendships.

Graql as a modeling language would be more powerful if it would allow specifying variadic relations, e.g. using ranges for the number of role-players for each role. This would cover this use case as well:

friendship sub relation,
  relates 2 friend;

Upvotes: 0

MiKo
MiKo

Reputation: 199

As Felix Chapman pointed out, role-types are unique, so a true symmetric relation is not possible.

There are a few ways around it; say you have defined your relation as

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

The first possibility is to use ako and abstract roles:

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

person isa entity-type plays-role friend;

The second possibility is using inference rules:

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

The second way makes the friendship relation a true symmetric relation from a mathematical point of view, but given Graql's match syntax and for performance reasons, there is rarely the need to explicitly make a relation symmetric, so I personally prefer the first way.

Upvotes: 0

Felix Chapman
Felix Chapman

Reputation: 91

Roles must be distinct, so you cannot have two friend roles in a single relation.

If the relation you are describing is symmetric, you should instead introduce two roles friend1 and friend2. If you want, these can both be ako friend.

Given the dataset you're using, it might be better to not describe this as a symmetric relationship and instead uses a knows relationship, where one role is the knower and the other role is known-about.

Upvotes: 1

Related Questions