如何使用Prolog / Eclipse语言从两个列表中找到集合交集?

时间:2014-04-29 00:26:52

标签: prolog eclipse-clp

所以在我开始之前,问题出在这里:

我有一个例子List Xs = [1,2,3]和List Ys = [2,3,4]。这两个列表中的两个共同元素成员是[2,3]。所以我试图创建一个谓词 setIntersection(Xs,Ys,Zs),其中结果列表([2,3])将绑定到Zs,并且我'我试图使用可以在Windows上的ECLiPSe程序上运行的Prolog语言来执行此操作,并且必须使用 循环迭代器,NO RECURSION

这是我到目前为止的代码:

setIntersection(Xs, Ys, Zs) :-
    ( foreach(Alpha, Xs), fromto([Ys], [Head|Tail], Tail, []), foreach(Bravo, Ys)
        do
             ( (Alpha =:= Head)
                   -> Bravo = Head;
                   fail
             )
    ).

我的代码的另一个版本是:

setIntersection(Xs, Ys, Zs) :-
    ( foreach(Alpha, Xs), param(Ys, Zs)
        do
             ( foreach(Bravo, Ys), foreach(Charlie, Zs), param(Alpha)
                   do
                         ( ( Alpha =:= Bravo)
                            -> Charlie is Alpha;
                            !
                         )
             )
    ).

结果(来自第二个代码):

?- setIntersection([1,2,3], [2,3,4], X).
X = [2, 3, _412]
Yes (0.00s cpu)

我得到的结果对于上面的代码来说非常奇怪。

请帮我解决这个问题,我将非常感激。谢谢!

1 个答案:

答案 0 :(得分:2)

我假设您需要使用ECLiPse声明性循环来执行此操作,但以防万一:您是否知道已在ECLiPSe中实现intersection/3

[eclipse]: intersection([1, 2, 3], [2, 3, 4], X).
X = [2, 3]
Yes (0.00s cpu)

以下是使用循环执行此操作的众多方法之一:

setIntersection(Xs, Ys, Zs) :-
    ( foreach(Xi, Xs), fromto([], ZsPrev, ZsCurr, Zs), param(Ys) do
        ( memberchk(Xi, Ys)  -> 
            ZsCurr = [Xi | ZsPrev]
        ;
            ZsCurr = ZsPrev
        )
    ).

试运行:

[eclipse]: setIntersection([1,2,3], [2,3,4], X).
X = [3, 2]
Yes (0.00s cpu)

与您在示例中提供的内容相比,元素的顺序相反,但是使用集合时,它们无关紧要。如果需要,您可以在最后反转或排序元素。

顺便说一句,为什么问题的标题中有“Perl”?