When working with a list sometimes there is a need to check that each item in a list is unique. This requires checking each pair of items. After a while the need to change the goal (unique
) to another goal is desired.
Here is some simple code that fills that need.
goal_list_combination(_,[]) :- !.
goal_list_combination(_,[_]) :- !.
goal_list_combination(Goal,[H0,H|T]) :-
goal_list_combination(Goal,H0,[H|T]),
goal_list_combination(Goal,[H|T]).
goal_list_combination(_,_,[]) :- !.
goal_list_combination(Goal,H0,[H|T]) :-
call(Goal,H0,H),
goal_list_combination(Goal,H0,T).
Here is the goal for unique
.
unique(A,B) :-
A \= B.
While an example run using the goal unique
is useful, it does not really demonstrate what is happening.
?- goal_list_combination(unique,[1,2,3,4]).
true.
?- goal_list_combination(unique,[1,2,2,4]).
false.
Using a less practical goal (write_values
) to write out the pairs gives some insight into what is happening.
Goal: write_values
write_values(A,B) :-
format('~w,~w~n',[A,B]).
Example run using the goal write_values
.
?- goal_list_combination(write_values,[1,2,3,4]).
1,2
1,3
1,4
2,3
2,4
3,4
true.
When looked at as part of a square matrix, it reveals that this is similar to an upper triangular matrix without the 0
s and the diagonal.
1 2 3 4
1 1,2 1,3 1,4
2 2,3 2,4
3 3,4
4
The predicate was only created for mode goal_list_combination(+,+)
.