SICStus Prolog:如何置换列表[0,1,2,3,5,5,7,8,9]

时间:2015-10-24 11:21:11

标签: list prolog permutation clpfd

我是Prolog的新手,我正在尝试列表排列谓词。

他们中的大多数都有两个论点(例如permutation/2)。

我希望创建一个只接受一个参数(列表)的程序,并查明列表中是否只有10个元素。

例如:

| ?- permutation([7, 1, 2, 3, 4, 5, 6, 0, 8, 9]).
yes

| ?- permutation(X).
X = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
...      

| ?- permutation([A,B,C,D,E,F,G,H,I,J]).
A = 0
B = 1
C = 2 
...
J = 9 ;

感谢任何提示!

2 个答案:

答案 0 :(得分:2)

更聪明地工作,而不是更努力: 使用

:- use_module(library(clpfd)).

使用length/2domain/2all_different/1labeling/2我们定义:

perm10(Zs) :-
   length(Zs,10),
   domain(Zs,0,9),
   all_different(Zs),
   labeling([],Zs).

考虑目标gen_perm([8,0,1,2,3,4,5,6,7,8])。 我们希望 1 失败,事实上,确实 ......
... 执行上述目标的工作量是多少?

让我们使用call_time/2测量运行时间 2

?- use_module(library(between),[repeat/1]).
true.

?- _Zs = [8,0,1,2,3,4,5,6,7,8], call_time((repeat(1000),gen_perm(_Zs);true),T_us).
T_us = 21940.

?- _Zs = [8,0,1,2,3,4,5,6,7,8], call_time((repeat(1000),perm10(_Zs)  ;true),T_us).
T_us = 10.

脚注1:列表中只有8个不同的整数,因此它不能是0到9之间所有整数的排列。
脚注2:使用SICStus Prolog版本4.3.2,x86_64-linux-glibc2.12。

答案 1 :(得分:0)

好的,谢谢你的回复!这有效:

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

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

gen_perm(List) :-
   perm([0,1,2,3,4,5,6,7,8,9],List),
   length(List,10).