0

我一直在尝试解决以下问题一段时间,但似乎找不到正确的解决方案。

假设有一个函数 test(X,Y,Z) 使得 X 是一对数字,Y 是对的列表,Z 是传递对的结果列表。

例如:

test((1,5), [(7,3),(5,2),(5,9)], Z).

Z = [(1,2),(1,9)]

(因为传递性 1->5->2 和 1->5->9)

到目前为止,我已经设法创建了以下代码:

test(_,[],_):- false.
test((X1,C),[(C,Y2)|_],(X1,Y2)).
test((X1,X2),[_|YT],Result) :- test((X1,X2),YT,Result).

它返回每个单独的结果对,如下所示:

Z = (1, 2) ;
Z = (1, 9) ;

但我似乎无法将它们全部返回到一个列表中,如上例所示:

Z = [(1,2),(1,9)]

任何帮助将不胜感激。

4

1 回答 1

2

我认为问题在于您没有构建传递对列表。您只是返回一对作为test/3.

这是一种可能的解决方案:

我做了一个谓词来处理比较对并描述他们的传递婚姻,这样我就不必在随后的规则中处理这些元组:

transit((X,T), (T,Y), (X,Y)).

那么这只是使用递归谓词进行标准列表处理的问题:

t(_, [], []).
t(X, [T|ToTransit], [Y|Transited]) :-
    transit(X,T,Y),
    t(X,ToTransit,Transited).
t(X, [T|ToTransit], Transited) :-
    \+ transit(X,T,_),
    t(X,ToTransit, Transited).

当然,一旦你有一个transit/3定义关系的谓词,你也可以做类似的事情

findall( TP,
         ( member(T, [(2,2), (2,5), (1,5)]), transit((1,2), T, TP) ),
         Tps). 
于 2013-10-28T21:16:29.890 回答