【问题标题】:Prolog: Determine if the intersection of two lists is emptyProlog:判断两个列表的交集是否为空
【发布时间】:2014-03-31 13:52:57
【问题描述】:

我试图弄清楚如何确定 Prolog 中两个列表的交集是否为空。据我了解,这是它们没有共同点。我是 Prolog 的新手(截至昨晚)。任何帮助是极大的赞赏。

这是我的尝试:

% returns true if head is not a member of List?
intersection([],_).
intersection([Head|Tail],List) :- 
   \+ member(Head,List),  
   intersection(Tail,List).

第二次尝试:

?- intersect([A,B,C,D],[E,F,G,H]).

intersect(L1,L2) :-
    intersection(L1,L2,[]).

mbratch 的解决方案解决了这个问题。

解决方案:

?-intersect([a,b,c,d],[e,f,g,h]).

intersect(L1,L2):-
    intersection(L1,L2,[]).

【问题讨论】:

  • 感谢您的回复。我仍然是假的,不知道我错过了什么。我更新了帖子。谢谢。
  • 您使用的是变量而不是原子。试试intersect([a,b,c,d], [e,f,g,h]). 如果你使用变量,Prolog 会说它们可以相交,因为它可以将AE 统一起来,因为它们是变量。变量以大写字母开头。原子(“常量”)以小写开头。
  • 这就是问题所在。谢谢。
  • @ mbratch intersection/3 不是 SWI-Prolog 内置谓词。这是lists 模块中定义的库谓词。在 SWI-Prolog 中,默认情况下,当调用其导出的谓词之一时,模块会自动加载。意识到 SWI-Prolog 自动加载将有助于避免将库谓词误认为内置谓词,这是 SO 上不幸的常见情况。
  • @PauloMoura 道歉。我站得更正了。由于我不需要包含任何特殊的库,所以我认为它是内置的。

标签: prolog


【解决方案1】:

与计算两个列表的交集相比,一种更有效的解决方案(通常)是在找到共同元素时立即失败:

empty_intersection(List1, List2) :-
    \+ (member(Element, List1), member(Element, List2)).

【讨论】:

    【解决方案2】:

    保持纯净!就像 1,2,3 一样简单:

    1. 使用maplist/2dif/2),我们定义list_nonmember/2
    list_nonmember(Xs,E) :- 地图列表(差异(E),Xs)。
    1. 使用maplist/2list_nonmember/2,我们定义none_intersect/2
    none_intersect(Xs,Ys) :- 地图列表(list_nonmember(Ys),Xs)。
    1. 准备好了!让我们运行一些查询!
    ?- none_intersect([a,b,c,d],[e,f,g,h])。 真的。 ?- none_intersect([a,b,c,d],[e,f,a,g,h])。 错误。 ?- none_intersect([a,b,g,c,d],[e,f,g,h])。 错误

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-30
      • 1970-01-01
      • 1970-01-01
      • 2019-03-24
      • 1970-01-01
      • 1970-01-01
      • 2011-02-25
      相关资源
      最近更新 更多