我是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 ;
感谢任何提示!
答案 0 :(得分:2)
更聪明地工作,而不是更努力: 使用clpfd!
:- use_module(library(clpfd)).
使用length/2
,domain/2
,all_different/1
和labeling/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).