繁体   English   中英

置换成SWI-Prolog列表

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM