prolog - 如何在不使用 findall 的情况下创建列表?序言

标签 prolog

我正在生成排列:

takeout(X,[X|T],T).
takeout(X,[F|R],[F|S]):-
    takeout(X,R,S).

perm([],[]).
perm([X|Y],Z):-
    perm(Y,W),
    takeout(X,Z,W).

我想知道如何在不使用 findall 的情况下创建所有排列的列表。

示例:

?-perm([1,2,3],List).
List = [[1, 2, 3], [2, 1, 3], [2, 3, 1], [1, 3, 2], [3, 1, 2], [3, 2, 1]]

最佳答案

按其开头的元素对排列进行分组。

  1. 获取一个元素 X 并创建排列 Ys1,但原始列表中不包含该元素。
  2. 添加此元素 X 作为所有这些排列的第一个元素,我们就得到了以 X 开头的排列列表 XP。 附加所有组将为您提供所有排列。
cons(X, Xs, [X|Xs]).
perm([], [[]]).
perm(Xs, Ys) :-
    dif(Xs, []),
    maplist({Xs}/[X, XP]>>(select(X, Xs, Xs1),
                           perm(Xs1, Ys1),
                           maplist(cons(X), Ys1, XP)),
            Xs, Yss),
    append(Yss, Ys).
?- perm([1, 2, 3], X).
X = [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] ;
false.
?- length(Y, 8), perm(Y, X), length(X, N). %8 factorial
N = 40320 

关于prolog - 如何在不使用 findall 的情况下创建列表?序言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65495313/

相关文章:

prolog - 具有一条规则的纯 Prolog 元解释器

prolog - 使用 SICStus Prolog 推广斐波那契数列

prolog - 某些特殊项的最坏情况指数运行时间

list - 递归结果存储在 Prolog 的列表中

c# - 使用 C# 的接口(interface)序言

java - 如何在 Android 上使用 swi-prolog

prolog - 从 prolog 中的函数返回一个值

list - 如何比较序言中的两个列表,如果第二个列表由列表一的所有其他元素组成,则返回 true?

string - 序言 : Remove extra spaces in a stream of characters

prolog - 如何获取可能的谓词值的列表