Prolog:找到两个列表的交集?

Prolog: finding intersection of two lists?

假设我有 Prolog 事实,例如:

fact1(x, [y1, y2, y3, y4]).

fact2(z1, [s, t, u, **y3**).
fact2(z2, [o, p, **y1**, q, r]).
fact2(z3, [**y1**, m, **y3**, n]).
fact2(z4, [j, k, **y4**, l]).
fact2(z5, [**y2**, d, e, f, g, h,  i]).
fact2(z6, [a, b, c, **y4**]).

而且,我想要一个查询,以便我得到所有与 x 相关的 'z'。

因此,此查询应输出 z1、z2、z3、z4、z5、z6,因为它们都包含元素 y1、y2、y3、and/or y4,因为它们与第一个 Prolog 中的 x 相关事实上

以下代码输出 fact2 的所有 z 关系:

fact2(_,X).

下面的代码输出x与fact1的关系:

fact1(x,X).

因此,我想我需要用下面的代码得到两个集合的交集,但它不起作用。

xyz(X):-
  intersection(fact2(_,X),fact2(x,X),X).

这行不通,有人可以指引我正确的方向吗?

通过查询,我需要得到的是:z1、z2、z3、z4、z5、z6,因为它们都包含 y1、y2、y3、and/or y4,因为这些都与 x int he first fact 有关。

如果您需要说明,请告诉我。谢谢。

您必须在不同的变量中实例化 fact2 和 fact1 上的每个术语,否则您将强制实例完全匹配。此外,去掉事实 "fact2" 上的星号,并在元素 y3 之后关闭第一个事实 "fact2" 中的钩子。 如果您想保留星号,请将它们括在单引号中。

fact1(x, [y1, y2, y3, y4]).

fact2(z1, [s, t, u, '**y3**']).
fact2(z2, [o, p, y1, q, r]).
fact2(z3, [y1, m, y3, n]).
fact2(z4, [j, k, y4, l]).
fact2(z5, [y2, d, e, f, g, h,  i]).
fact2(z6, [a, b, c, y4]).
xyz(Z):-  fact2(Z,X),fact1(_,Y), intersection(X,Y,I), I\=[].

然后试着问:

?- xyz(X)

或者,如果您希望所有答案都在一个列表中,则为 L:

?- setof(Z, xyz(Z), L).

这个片段

xyz(L):-
    fact1(x, L1),
    setof(K, L2^I^(fact2(K, L2), intersection(L1,L2,I), I \= []), L).

产量

?- xyz(L).
L = [z1, z2, z3, z4, z5, z6].