0

我试图让foreach/2循环在 Prolog 中工作(使用 tkeclipse)。我知道它需要第一个参数中的一个元素和一个列表来搜索该元素作为第二个参数。

我的问题是,尽管尝试重写我的代码并在线寻找解决方案,但我仍然无法使其工作。

在下面的代码中,我尝试编写一个谓词visite/2,它接受博物馆列表并返回它们所在城市的列表。

非常感谢您的帮助,因为它可以让我为即将到来的考试做好更好的准备。

musee(paris,louvre).
musee(rome,vatican).
musee(madrid,prado).
musee(berlin,kulturforum).
musee(londres,british_museum).

visite([X],L) :-
  findall(V,musee(V,_),List),
  (
    foreach(X,List) do findall(C,musee(C,X),L)
  ).
4

2 回答 2

1

ECLiPSe 的 do-loops 是以简洁的方式编写迭代递归的简写。您的示例的一个简单应用程序是

visite(Ms, Cs) :-
    ( foreach(M,Ms), foreach(C,Cs) do
        musee(C, M)
    ).

这(模非确定性)等价于显式递归形式

visite([], []).
visite([M|Ms], [C|Cs]) :-
    musee(C, M),
    visite(Ms, Cs).

解决问题的算法完全不同的方法是使用回溯和 findall,如

visite(Ms, Cs) :-
    findall(C, (member(M, Ms), musee(C, M)), Cs).

两者都是有用的 Prolog 编程模式。

于 2021-06-25T20:39:22.010 回答
0

这不是 Prolog(至少,不是我所知道的)。

如果是这样,迭代循环的概念与 Prolog 是对立的。

你的问题陈述:

我[正在尝试编写]一个谓词visite/2,它接受博物馆列表并返回它们所在城市的列表

可以以对 Prolog 更惯用的方式更好地完成。像这样的东西:

musee( paris   , louvre         ).
musee( rome    , vatican        ).
musee( madrid  , prado          ).
musee( berlin  , kulturforum    ).
musee( londres , british_museum ).

%
% Accepts a list of museums and returns the list of cities (villes) in which they are found.
% Or... vice versa.
% 
% We invoke a helper predicate that will prevent problems if/when the predicate
% is used in a generative manner.
visite( Ms,Vs ) :- visite( Ms, [], Vs ).

visite( []     , _ , []     ) .
visite( [M|Ms] , T , [V|Vs] ) :-
  musee(V,M) ,
  \+ member( M:V, T ),
  !,
  visite( Ms, [M:V|T], Vs )
  .


于 2021-06-23T21:57:55.547 回答