【问题标题】:Group facts in prolog by 3 variablesprolog 中的事实按 3 个变量分组
【发布时间】:2018-12-26 17:06:26
【问题描述】:

我在按 3 个不同的属性对 prolog 中的一些事实进行分组时遇到了麻烦。 这是我的知识库(基本上是一个图表):

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

唉, 我自己也不太了解prolog, 我希望你甚至可以建议我一个更好的解决方案。

非常感谢

【问题讨论】:

    标签: prolog grouping


    【解决方案1】:

    所以,

    这是我的尝试。它确实有效,但如果存在更好的解决方案,请告诉我(考虑从列表中删除重复项的重复数据删除规则)

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

    没关系

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-04
      • 2013-08-31
      • 1970-01-01
      • 2020-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多