Get repeat answers when comparing facts in prolog
Working with SWI-Prolog. I have a list of ranks say:
rank(London, 3.5开发者_运维技巧).
rank(New York, 3.5).
rank(Seattle, 2.3).
And I am trying to get my head around making a rule that prints/returns any facts with the same rank. So in this case it would come back with London & New York.
Here's what I've come up with so far, the only problem is the duplicates I get with it (although they make perfect sense with the current rule). Would using recursion somehow help this?
equal_rank(_):-
rank(U1, R1),
rank(U2, R2),
U1 \== U2,
R1 == R2,
print(R1), print(': '), print(U1), print(', '), print(U2), nl,
fail.
The output would be:
3.5: London, New York
3.5: New York, London
I just can't figure out how to stop that second line.
A simple approach would be to replace the not-equal test between U1 and U2 with a less-than test:
U1 @< U2.
This way a given pair only appears once.
I would probably go for something that uses bagof/3
, but I don't know whether that's the preferred or more apt approach for the problem you have at hand. With the facts you defined, the following goal seems to issue the result you want:
| ?- bagof(C, rank(C, X), Cs), length(Cs, L), L > 1.
Cs = [london,'new york']
L = 2
X = 3.5
yes
It needs some work on formatting, of course; the idea of collecting results in a list may or may not be useful to you. Oh, and by the way, I was unsure about city names needing to be variables, so as you can see I have asserted rank/2
facts using plain atoms.
For a little bit of additional information on bagof/3
, you may consult the online SWI-Prolog manual page about it.
精彩评论