另一种指定此模式的方法:
two_ones_n_zeros(N, L) :-
length(Z, N),
maplist(=(0), Z),
nth1(I, L0, 1, Z),
nth1(J, L, 1, L0),
I < J.
例子:
?- two_ones_n_zeros(2, L).
L = [1, 1, 0, 0] ;
L = [1, 0, 1, 0] ;
L = [1, 0, 0, 1] ;
L = [0, 1, 1, 0] ;
L = [0, 1, 0, 1] ;
L = [0, 0, 1, 1] ;
false.
不同方法的效率比较
two_ones_n_zeros_dcg(N, L) :-
M is N + 2,
length(L, M),
phrase((zeros, [1], zeros, [1], zeros), L).
two --> [1], one ; [0], two.
one --> [1], zeros ; [0], one.
zeros --> [] ; [0], zeros.
:- use_module(library(clpfd)).
two_ones_n_zeros_clp(N, L) :-
M is N + 2,
length(L, M),
twoones(L),
labeling([], L).
twoones(Bs) :-
Bs ins 0..1,
sum(Bs, #=, 2).
comparison(N) :-
write('\nLists: '),
garbage_collect,
time(forall(two_ones_n_zeros(N, _), true)),
write('\nDCG: '),
garbage_collect,
time(forall(two_ones_n_zeros_dcg(N, _), true)),
write('\nCLP: '),
garbage_collect,
time(forall(two_ones_n_zeros_clp(N, _), true)).
经验结果,使用 swi-prolog(版本 8.4.2):
?- two_ones_n_zeros(1, L1).
L1 = [1, 1, 0] ;
L1 = [1, 0, 1] ;
L1 = [0, 1, 1] ;
false.
?- two_ones_n_zeros_dcg(1, L1).
L1 = [1, 1, 0] ;
L1 = [1, 0, 1] ;
L1 = [0, 1, 1] ;
false.
?- two_ones_n_zeros_clp(1, L1).
L1 = [0, 1, 1] ;
L1 = [1, 0, 1] ;
L1 = [1, 1, 0].
?- comparison(400).
Lists:
% 323,613 inferences, 0.031 CPU in 0.031 seconds (100% CPU, 10355616 Lips)
DCG:
% 11,152,272 inferences, 0.391 CPU in 0.391 seconds (100% CPU, 28549816 Lips)
CLP:
% 1,302,560,369 inferences, 94.063 CPU in 94.110 seconds (100% CPU, 13847818 Lips)
true.