I have a set of definitions of the form pair/2
and a predicate propagate/3
:
pair(1, 2).
pair(2, 3).
pair(3, 4).
pair(4, 5).
propagate([], _, []) :- !.
propagate([pair(N, Num)|Tail], Num, [N|ResultTail]) :-
propagate(Tail, Num, ResultTail), !.
propagate([pair(Num, N)|Tail], Num, [N|ResultTail]) :-
propagate(Tail, Num, ResultTail), !.
propagate([_|Tail], Num, Result) :-
propagate(Tail, Num, Result), !.
If I have List = [pair(1, 2), pair(2, 3), pair(3, 4), pair(4, 5)]
and I do
propagate(List, 2, Result).
I get the desired output, Result = [1, 3]
; i.e. the list of all numbers that form a pair with 2
.
However, if I have List = [pair(N1, N2), pair(N2, N3), pair(N3, N4), pair(N4, N5)]
and if I do
propagate(List, N2, Result)
then the output is
N2 = N3, N3 = N4, N4 = N5,
Result = [N1, N5, N5, N5].
I would like the output to be Result = [N1, N3]
, instead. How can I do that?
(==)/2 does the trick
propagate([], _, []) :- !.
propagate([pair(N, X)|Tail], Num, [N|ResultTail]) :-
X == Num,
propagate(Tail, Num, ResultTail), !.
propagate([pair(X, N)|Tail], Num, [N|ResultTail]) :-
X == Num,
propagate(Tail, Num, ResultTail), !.
propagate([_|Tail], Num, Result) :-
propagate(Tail, Num, Result), !.
yields
?- List = [pair(N1, N2), pair(N2, N3), pair(N3, N4), pair(N4, N5)], propagate(List,N2,Result).
List = [pair(N1, N2), pair(N2, N3), pair(N3, N4), pair(N4, N5)],
Result = [N1, N3].
Note that facts pair/2 don't play any role in your program, and that you should query a variable shared (I used N2
instead of P2
).
Also, why all those cuts at rules' end ? Useless cuts are often dangerous.