[英]Permute into a list SWI-Prolog
如何使用permute谓词输出到SWI prolog中的列表?
permutation / 2谓词一次只返回一个结果。
描述所有排列的最直接的方法是使用bagof/3
。 请注意, findall/3
不能直接使用,因为findall
会生成原始列表的文字副本。
list_allperms(L, Ps) :-
bagof(P, permutation(L,P), Ps).
?- L = [A,B,C], list_allperms(L, Ps).
L = [A, B, C],
Ps = [[A, B, C], [A, C, B], [B, A, C], [B, C, A], [C, A, B], [C, B, A]].
所以这是毫无疑问的版本。 但是你甚至可以在没有任何辅助内置函数的情况下直接在纯Prolog中实现它。
如果你想要一个所有排列的列表,findall / 3就是你要走的路。 如果要打印,可以使用forall / 2。 两种情况:
case_a(In, L) :- findall(Perm, permutation(In, Perm), L).
case_b(In) :- forall(permutation(In, Perm), writeln(Perm)).
forall它是一个通用的内置程序,实现了一个故障驱动的循环,其简单性令人惊叹。 我从SWI-Prolog库中报告了这个定义,我觉得它很有意思。
%% forall(+Condition, +Action)
%
% True if Action if true for all variable bindings for which Condition
% if true.
forall(Cond, Action) :-
\+ (Cond, \+ Action).
编辑:
如上所述,如果你的列表中有变量,你应该知道findall / 3 WRT bagof / 3的不同行为:
?- case_a([1,2,3],X).
X = [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]].
?- case_a([A,B,C],X).
X = [[_G467, _G470, _G473], [_G455, _G458, _G461], [_G443, _G446, _G449], [_G431, _G434, _G437], [_G419, _G422, _G425], [_G407, _G410, _G413]].
请注意,第二个查询输出中的每个变量都是不同的:可能是请求结果,也可能不是,具体取决于手头的问题。 确定适当的行为WRT变量量化在变量是数据的限制类问题中是强制性的,即元编程,我认为......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.