Prolog 在不创建新统一的情况下查找值

Prolog 在不创建新统一的情况下查找值,prolog,unification,Prolog,Unification,我有一组形式为pair/2的定义和一个谓词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|Res

我有一组形式为
pair/2
的定义和一个谓词
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), !.
如果我有
List=[对(1,2),对(2,3),对(3,4),对(4,5)]
我有

propagate(List, 2, Result).
我得到了所需的输出,
Result=[1,3]
;i、 e.与
2
成对的所有数字的列表

但是,如果我有
List=[pair(N1,N2),pair(N2,N3),pair(N3,N4),pair(N4,N5)]
并且如果我有

propagate(List, N2, Result)
然后输出为

N2 = N3, N3 = N4, N4 = N5,
Result = [N1, N5, N5, N5].
我希望输出为
Result=[N1,N3]
。我怎样才能做到这一点呢?

()/2起作用

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), !.
屈服

?- 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].
请注意事实对/2在您的程序中不起任何作用,您应该查询共享的变量(我使用了
N2
而不是
P2


还有,为什么要在规则的末尾进行这些削减?无用的切割通常是危险的。

是的,那是一个打字错误。我的意思是
N2
,而不是
P2
。我过去经常剪,因为我希望它在只找到一个匹配项时停止。我真的不知道如何使用Prolog,所以我可能已经做了一些无用的事情。“我希望它在只找到一个匹配项时停止”这是预期的用途,好吧,但是在需要剪切的地方:
传播([pair(N,X)| Tail],Num,[N | ResultTail]):-X==Num!,传播(尾部、数值、结果尾)。