Comme il est, Franz' solution ne fonctionnera pas: il renvoie des triplets de prople qui parlent la même langue, mais ces triplets peuvent contenir des doublons. Ainsi, il faudrait toujours recourir, par exemple, à sort/2
et length/2
pour trouver la réponse à la question initiale:
?- findspeakers(Language, X1, X2, X3), sort([X1, X2, X3], Y), length(Y, 3).
false.
(La réponse est pas, il n'y a pas trois personnes parlant la même langue.) Quoi qu'il en soit, je pense une solution plus élégante existe:
spoken(L, S) :-
speaks(S, LL), member(L, LL).
same_language(N, L, SS) :-
bagof(S, spoken(L, S), SS), length(SS, N).
Le prédicat spoken/2
utilise member/2
et réussit si la langue est parlée par L
personne S
. same_language/3
réussit si la liste SS
contient N
personnes distinctes, toutes parlant la langue L
. Ce prédicat utilise bagof/3
; Si la définition du prédicat speak/2
contient des données en double, vous devez utiliser setof/3
à la place.
Notez que ce bien le problème se généralise: nous pouvons maintenant répondre à la question pour touten, non seulement 3. Démonstration:
?- same_language(3, L, SS).
false.
?- same_language(2, L, SS).
L = dutch,
SS = [fred, mary] ;
L = english,
SS = [fred, jim] ;
false.
devrait-il pas être 'parle (fred, [allemand , anglais, néerlandais]). '(remarquez la virgule supplémentaire)? Aussi: est ce devoir? Si oui, merci de l'indiquer comme devoirs. – Franz
Il a une odeur de travail. – nedned