Группировать факты в прологе по 3 переменным - PullRequest
0 голосов
/ 26 декабря 2018

У меня проблемы с группировкой некоторых фактов в прологе по 3 различным свойствам.Это моя база знаний (график в основном):

% entity(Label, Id)
% relationship(Type, Subject, Object)

entity('Person', id_0).

entity('Place', 1468).
relationship('wasIn', id_0, 1468).
entity('Place', 1367).
relationship('wasIn', 1468, 1367).
entity('Person', 1466).
relationship('wasIn', 1466, 1468).
entity('Place', 1478).
relationship('aliasOf', 1478, 1468).

entity('Place', 1052).
relationship('wasIn', id_0, 1052).
entity('Place', 1184).
relationship('wasIn', 1052, 1184).
entity('Person', 1048).
relationship('wasIn', 1048, 1052).

entity('Place', 1069).
relationship('wasIn', id_0, 1069).
entity('Place', 1070).
relationship('wasIn', 1069, 1070).
entity('Person', 1068).
relationship('wasIn', 1068, 1069).

Я хотел сгруппировать отношения по каждому идентификатору сущности и типу субъекта, чтобы получить что-то вроде:

[
    [
        [id_0, wasIn, Place],
        % because entities 1468, 1052, 1069 are Places
        [ relationship(wasIn, id_0, 1468),
          relationship(wasIn, id_0, 1052),
          relationship(wasIn, id_0, 1069)]
    ],
    [
        [id_0, wasIn, Some Other Subject Label],
        [relationship(wasIn, id_0, ...),
        ...]
    ],
    [
        [1468, wasIn, Place],
        [relationship(wasIn, 1468, ...),
        ...]
    ],
    ...
]

и т. Д.далее.

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

group_relationships_by_node([[Subject, Type] | [R]]) :-
    entity(_, Subject),
    relationship(Type, Subject, _),
    findall(relationship(Type, Subject, Object), relationship(Type, Subject, Object), R).

group_by_relationships(Result) :-
    findall(X, group_relationships_by_node(X), Result).

это мой текущий результат:

[
  [
    [id_0, wasIn],
    [ relationship(wasIn, id_0, 1468),
      relationship(wasIn, id_0, 1052),
      relationship(wasIn, id_0, 1069) ]
  ],
  % duplicate
  [
    [id_0, wasIn],
    [ relationship(wasIn, id_0, 1468),
      relationship(wasIn, id_0, 1052),
      relationship(wasIn, id_0, 1069) ]
  ],
  % duplicate
  [
    [id_0, wasIn],
    [ relationship(wasIn, id_0, 1468),
      relationship(wasIn, id_0, 1052),
      relationship(wasIn, id_0, 1069) ]
  ],
  [
    [ 1468, wasIn ],
    [ relationship(wasIn, 1468, 1367) ]
  ],
  [
    [ 1466, wasIn ],
    [ relationship(wasIn, 1466, 1468) ]
  ],
  [
    [ 1478, aliasOf ],
    [ relationship(aliasOf, 1478, 1468) ]
  ],
  [
    [ 1052, wasIn ],
    [ relationship(wasIn, 1052, 1184) ]
  ],
  [
    [ 1048, wasIn ],
    [ relationship(wasIn, 1048, 1052) ]
  ],
  [
    [ 1069, wasIn ],
    [ relationship(wasIn, 1069, 1070) ]
  ],
  [
    [ 1068, wasIn ],
    [ relationship(wasIn, 1068, 1069) ]
  ]
]

Увы, я сам не очень хорошо знаю пролог, надеюсь, вы даже можете предложить мнелучшее решение.

Большое спасибо

1 Ответ

0 голосов
/ 27 декабря 2018

Итак,

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

get_subject_ids(Subjects) :-
    findall(Subject, entity(_, Subject), Subjects).

get_relationship_by_type_subject_objectLabel(Type, Subject, ObjectLabel, Result) :-
    entity(ObjectLabel, Object),
    relationship(Type, Subject, Object),
    Result = relationship(Type, Subject, Object).

iterate_labels(_, _, [], []).
iterate_labels(Subject, Type, [ObjectLabel | Rest], [[ObjectLabel, Result] | ResultRest]) :-
    findall(Rel, get_relationship_by_type_subject_objectLabel(Type, Subject, ObjectLabel, Rel), Result),
    iterate_labels(Subject, Type, Rest, ResultRest).

iterate_objects([], []).
iterate_objects([Object | Rest], [ObjectLabel | ResultRest]) :-
    entity(ObjectLabel, Object),
    iterate_objects(Rest, ResultRest).

iterate_types(_, [], []).
iterate_types(Subject, [Type | Rest], [[Type, GroupedRels] | ResultRest]) :-
    % find all relationships with type Type starting from Subject
    % findall(relationship(Type, Subject, Object), relationship(Type, Subject, Object), Rels),
    findall(Object, relationship(Type, Subject, Object), Objects),
    iterate_objects(Objects, MObjects),
    dedup(MObjects, ObjectLabels),
    iterate_labels(Subject, Type, ObjectLabels, GroupedRels),
    iterate_types(Subject, Rest, ResultRest).

iterate_subjects([], []).
iterate_subjects([Subject | Rest], [[Subject, Result] | ResultRest]) :-
    findall(Type, relationship(Type, Subject, _), DTypes),
    dedup(DTypes, Types),
    iterate_types(Subject, Types, Result),
    iterate_subjects(Rest, ResultRest).

main :-
    get_subject_ids(Subjects),
    iterate_subjects(Subjects, Result),
    writeln(Result).

Результат примерно такой:

[
  [
    id_0,
    [
      [
        wasIn,
        [
          [
            Place,
            [
              relationship(wasIn,
              id_0,
              1468),
              relationship(wasIn,
              id_0,
              1052)
            ]
          ],
          [
            Placez,
            [
              relationship(wasIn,
              id_0,
              1069)
            ]
          ]
        ]
      ]
    ]
  ],
  [
    1468,
    [
      [
        wasIn,
        [
          [
            Place,
            [
              relationship(wasIn,
              1468,
              1367)
            ]
          ]
        ]
      ]
    ]
  ],
  [
    1367,
    [

    ]
  ],
  [
    1466,
    [
      [
        wasIn,
        [
          [
            Place,
            [
              relationship(wasIn,
              1466,
              1468)
            ]
          ]
        ]
      ]
    ]
  ],
  [
    1478,
    [
      [
        aliasOf,
        [
          [
            Place,
            [
              relationship(aliasOf,
              1478,
              1468)
            ]
          ]
        ]
      ]
    ]
  ],
  [
    1052,
    [
      [
        wasIn,
        [
          [
            Place,
            [
              relationship(wasIn,
              1052,
              1184)
            ]
          ]
        ]
      ]
    ]
  ],
  [
    1184,
    [

    ]
  ],
  [
    1048,
    [
      [
        wasIn,
        [
          [
            Place,
            [
              relationship(wasIn,
              1048,
              1052)
            ]
          ]
        ]
      ]
    ]
  ],
  [
    1069,
    [
      [
        wasIn,
        [
          [
            Place,
            [
              relationship(wasIn,
              1069,
              1070)
            ]
          ]
        ]
      ]
    ]
  ],
  [
    1070,
    [

    ]
  ],
  [
    1068,
    [
      [
        wasIn,
        [
          [
            Placez,
            [
              relationship(wasIn,
              1068,
              1069)
            ]
          ]
        ]
      ]
    ]
  ]
]

что хорошо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...