Reputation: 1
I am trying to get the foreach/2
loop to work in Prolog (using tkeclipse). I understand it needs an element in the first argument and a list to search for that element within as a second argument.
My problem is that I haven't been able to make it work despite trying to rewrite my code and looking for solutions online.
In the following code, I try to write a predicate visite/2
that takes a list of museums and returns a list of cities where they are located.
Your help would be really appreciated as it would allow me to be better prepared for my upcoming exam.
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)
).
Upvotes: 0
Views: 169
Reputation: 5034
ECLiPSe's do-loops are a shorthand for writing iterative recursions in a concise way. A simple application to your example would be
visite(Ms, Cs) :-
( foreach(M,Ms), foreach(C,Cs) do
musee(C, M)
).
which is (modulo nondeterminism) equivalent to the explicit recursive form
visite([], []).
visite([M|Ms], [C|Cs]) :-
musee(C, M),
visite(Ms, Cs).
An algorithmically completely different way to solve your problem is using backtracking and findall, as in
visite(Ms, Cs) :-
findall(C, (member(M, Ms), musee(C, M)), Cs).
Both are useful Prolog programming patterns.
Upvotes: 1
Reputation: 74277
This isn't Prolog (at least, not as I know it).
And if it were, the notion of an iterative loop is antithetic to Prolog.
Your problem statement:
I [am trying to write] a predicate
visite/2
that takes a list of museums and returns a list of cities where they are located
could be better done in a way more idiomatic to Prolog. Something like this:
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 )
.
Upvotes: 0