Код, представленный в этом предыдущем ответе , весьма универсален - благодаря clpfd .
Есть ли недостатки?Да, есть и обратная сторона: Неэффективность!
В этом ответе мы улучшаем производительность и сохраняем универсальность.
:- use_module(<a href="http://www.swi-prolog.org/man/clpfd.html" rel="nofollow noreferrer">library(clpfd)</a>).
Мы действуем как этот предыдущий ответ сделал, когда он определил предикат fd_length/2
:
list_nth0_item_replaced__NEW(Es, N, X, Xs) :-
list_index0_index_item_replaced(Es, 0,N, X, Xs).
list_index0_index_item_replaced([_|Es], I ,I, X, [X|Es]).
list_index0_index_item_replaced([E|Es], I0,I, X, [E|Xs]) :-
I0 #< I,
I1 #= I0+1,
list_index0_index_item_replaced(Es, I1,I, X, Xs).
Итак ... он стал быстрее?
?- numlist(1,100000,Zs), time(list_nth0_item_replaced(Zs,99999,x,Xs)).
% <b>14,499,855</b> inferences, 0.893 CPU in 0.893 seconds (100% CPU, 16237725 Lips)
Zs = [1, 2, 3, 4, 5, 6, 7, 8, 9|...],
Xs = [1, 2, 3, 4, 5, 6, 7, 8, 9|...] ;
% 7 inferences, 0.000 CPU in 0.000 seconds (99% CPU, 18377 Lips)
false.
?- numlist(1,100000,Zs), time(list_nth0_item_replaced<b>__NEW</b>(Zs,99999,x,Xs)).
% <b>499,996</b> inferences, 0.049 CPU in 0.049 seconds (100% CPU, 10158710 Lips)
Zs = [1, 2, 3, 4, 5, 6, 7, 8, 9|...],
Xs = [1, 2, 3, 4, 5, 6, 7, 8, 9|...] ;
% 6 inferences, 0.000 CPU in 0.000 seconds (93% CPU, 213988 Lips)
false.
Хорошо, это быстрее .Но все еще универсально?
?- list_nth0_item_replaced__NEW([a,b,c,d], 1, z, Xs).
Xs = [a,z,c,d]
; false.
?- list_nth0_item_replaced__NEW(Xs, 1, z, [a,z,c,d]).
Xs = [a,_A,c,d]
; false.
?- list_nth0_item_replaced__NEW(Es, N, X, [a,z,c,d]).
N = 0, X = a, Es = [_A, z, c, d],
; N = 1, X = z, Es = [ a,_A, c, d]
; N = 2, X = c, Es = [ a, z,_A, d],
; N = 3, X = d, Es = [ a, z, c,_A]
; false.
?- list_nth0_item_replaced__NEW([a,b,c,d], N, X, Xs).
N = 0, Xs = [X,b,c,d]
; N = 1, Xs = [a,X,c,d]
; N = 2, Xs = [a,b,X,d]
; N = 3, Xs = [a,b,c,X]
; false.
Выглядит хорошо для меня!