0

所以在我开始之前,这里有一个问题:

我有一个示例 List Xs = [1,2,3] 和 List Ys = [2,3,4]。这两个列表中的两个常见元素成员是 [2,3]。所以我正在尝试创建一个谓词setIntersection(Xs, Ys, Zs),其中结果列表( [2,3] )将绑定到 Zs,我正在尝试使用 Prolog 语言来做到这一点在 Windows 上的 ECLiPSe 程序上运行,它必须使用循环迭代器,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)

对于上面的代码,我得到的结果很奇怪。

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

4

1 回答 1

2

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

[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”在问题的标题中?

于 2014-04-29T00:54:57.530 回答