通过3个变量将序言中的事实分组

时间:2018-12-26 17:06:27

标签: prolog grouping

我很难按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和主题类型对关系进行分组,以便获得如下信息:

[
    [
        [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) ]
  ]
]

A, 我自己不太了解序言, 我希望您甚至可以建议我一个更好的解决方案。

非常感谢您

1 个答案:

答案 0 :(得分:0)

所以

这是我的尝试。它确实可以工作,但是请告诉我是否存在更好的解决方案(考虑从列表中删除重复项的dedup规则)

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)
            ]
          ]
        ]
      ]
    ]
  ]
]

很好