我一直试图解决以下问题一段时间,但似乎找不到合适的解决方案。
假设有一个函数测试(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)]
非常感谢任何帮助。
答案 0 :(得分: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).