문제

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top