【问题标题】:Verifying intersection of two lists in Prolog在 Prolog 中验证两个列表的交集
【发布时间】:2024-01-09 12:59:01
【问题描述】:

我正在尝试检查提供的交互是否是两个列表的正确交集。示例查询列表:

?- intersectionL([1,2,3,4],[1,3,5,6],[1,3]).
/* expected output: true. */

?- intersectionL([1,2,3,4],[1,3,5,6],X).
/* expected output: X = [1,3]. */

?- intersectionL([1,2,3],[4,3],[3]).
/* expected output: true. */

我写了一个函数来计算两个列表的交集(intersectionL)。从那里我想验证给定的第三个参数是否与我找到的交集(intersectionHelper)相同。

intersectHelper([], []).
intersectHelper([H1|T1], [H2|T2]):-
    H1 = H2, intersectHelper(T1, T2).

intersectionL([], X, []). 
intersectionL([H1|T1], L2, [H1|Res]):- 
  member(H1, L2), intersectionL(T1, L2, Res). 
  intersectionL([X|T1], L2, Res):- 
    intersectionL(T1, L2, Res).

我有两个问题:首先,我如何在intersectionL 中使用intersectionHelper。其次,如果没有提供列表(如上面的查询 2),我如何输出交叉点列表。

编辑:我能够为其他感兴趣的人解决它。我不需要intersectionHelper。

intersectionL([], X, []). 
intersectionL([H1|T1], L2, [H1|Res]):- 
  member(H1, L2), intersectionL(T1, L2, Res). 
  intersectionL([X|T1], L2, Res):- 
    intersectionL(T1, L2, Res).

【问题讨论】:

  • 为什么首先需要intersectionHelper/2
  • 我认为对于上面的 1 和 3 之类的查询,这是正确的方法。我还能怎么做?

标签: prolog


【解决方案1】:

不是答案,但我注意到intersectionL/3 中缺少 RED CUT:

例如,计算[1,2,3][1,4,5] 的交集给出了两种解决方案,只需要其中一种:

?- intersectionL([1,2,3],[1,4,5],L).
L = [1] ;  % desired
L = [].    % not desired

我们需要在第二个子句中添加一个保护条件:

intersectionL([], X, []). 

intersectionL([H1|T1], L2, [H1|Res]):- 
  member(H1, L2), intersectionL(T1, L2, Res). 

intersectionL([X|T1], L2, Res):- 
  \+member(H1, L2), intersectionL(T1, L2, Res).

或者使用“red cut”告诉 Prolog 如果第二个子句成功了就不要尝试第三个子句(这很难看):

intersectionL([], X, []). 

intersectionL([H1|T1], L2, [H1|Res]):- 
  member(H1, L2),!,intersectionL(T1, L2, Res). 

intersectionL([X|T1], L2, Res):- 
  intersectionL(T1, L2, Res).

最好有一个带有绿色切割的显式守卫来摆脱任何无用的选择点,同时仍然保持声明性:

intersectionL([], _, []). 

intersectionL([H1|T1], L2, [H1|Res]):- 
  member(H1, L2),!,intersectionL(T1, L2, Res). 

intersectionL([H1|T1], L2, Res):- 
  \+member(H1, L2),!,intersectionL(T1, L2, Res).

现在可以了,只有一个解决方案。

?- intersectionL([1,2,3],[1,4,5],L).
L = [1].

【讨论】:

    最近更新 更多