Reputation: 371
I have this list (read from a file): [a-3,a-2,a-1,b-3,b-2,b-1,c-3,c-2,c-1,end_of_file]
Also i have the following predicates:
% ipo(A,B) -> A is preferred over B
ipo(end_of_file, _).
ipo(c-3,a-3).
ipo(c-3,b-3).
ipo(c-3,b-2).
ipo(a-2,c-3).
ipo(a-2,b-2).
% gr(A,B) -> A is better than B | for example a-2 is better than a-3
% for same key, the lower value is better
% also A is better than B if A is preferred over B
gr(X-I, X-J):- I<J.
gr(A, B):- ipo(A,B).
psort(>, E1, E2):- gr(E1, E2).
psort(<, E1, E2):- \+ gr(E1, E2).
rank(In, Out):-
predsort(psort, In, Out).
The predicate rank(In, Out) uses psort as a predicate for predsort to sort my list for preference. Except it doesn't.
The input: rank([a-3,a-2,a-1,b-3,b-2,b-1,c-3,c-2,c-1,end_of_file], Sorted).
The actual output: Sorted = [a-3, a-2, a-1, b-3, b-2, b-1, c-3, c-2, c-1, end_of_file].
The expected output: Sorted = [a-3, b-3, b-2, b-1, c-3, a-2, a-1, c-2, c-1, end_of_file].
The output does not have to be unique. Important to the task at hand is the the preference facts are accounted for.
EDIT
Using the helpful suggestions from CapelliC i managed to advance my program to the following:
ipo(c-3,a-3).
ipo(c-3,b-3).
ipo(c-3,b-2).
ipo(b-1,c-3).
ipo(a-2,c-3).
ipo(a-2,b-2).
gr(X-I, X-J):- !, I<J.
gr(A, B):- ipo(A,B).
psort(>, E1, E2):- gr(E1, E2).
psort(<, _E1, _E2).
rank(In, Out):-
predsort(psort, In, Out).
The following test run, still shows erroneous output. That is 'b-2' should never be to the left of the 'b-3' because according to gr(2) b-2 is better than b-3.
?- combinations(L), append(L1, [_], L), rank(L1, Sorted).
L = [a-3, a-2, a-1, b-3, b-2, b-1, c-3, c-2, c-1, end_of_file],
L1 = [a-3, a-2, a-1, b-3, b-2, b-1, c-3, c-2, c-1],
Sorted = [a-3, b-2, c-3, a-2, a-1, b-3, b-1, c-2, c-1] .
Upvotes: 2
Views: 662
Reputation: 60014
About efficiency: I've changed your code to
gr(X-I, X-J):- !, I<J.
gr(A, B):- ipo(A,B).
psort(>, E1, E2):- gr(E1, E2).
psort(<, _E1, _E2).
(the cut means there is no point is examining the ipo/2 relation, when the same first element of pairs has been seen)
The outcome seems appropriate:
?- rank([c-3,a-2,a-3,a-1], Sorted).
Sorted = [a-3, c-3, a-2, a-1].
Of course, it's sorted from lower to higher preference. Just reverse it when done, or swap the operators in psort/3:
psort(<, E1, E2):- gr(E1, E2).
psort(>, _E1, _E2).
?- rank([c-3,a-2,a-3,a-1], Sorted).
Sorted = [a-1, a-2, c-3, a-3].
I would exclude end_of_file
from the input list, and ipo/2 also, to clean up the specification. If it's not possible to correct the input 'routine', you could do
?- append(L, [_], [c-3,a-2,a-3,a-1,end_of_file]).
L = [c-3, a-2, a-3, a-1]
Last, ipo/2 seems incomplete (isn't c-3 preferred over a-1 ? I guess so...). A possible simple solution could be to left undefined the numeric field:
ipo(c-_, a-_).
...
Upvotes: 2