Сохранение логической чистоты с использованием встроенных предикатов same_length/2
, length/2
и append/3
!
replace_at(I,X,Xs0,Xs2) :-
same_length(Xs0,Xs2),
append(Prefix,[_|Xs1],Xs0),
length([_|Prefix],I),
append(Prefix,[X|Xs1],Xs2).
Сначала давайте запустим пример запроса, который использовал @magusв предыдущий ответ на этот вопрос:
?- replace_at(3,0,[1,2,3,4,5,6],Xs).
Xs = [1,2,0,4,5,6] ;
false.
Работает ли это, когда элементы списка создаются позже?
?- replace_at(3,0,[A,B,C,D,E,F],Xs), A=1,B=2,C=3,D=4,E=5,F=6.
A = 1, B = 2, C = 3, D = 4, E = 5, F = 6, Xs = [1,2,0,4,5,6] ;
false.
Да! * 1018Что делать, если индекс не конкретное целое число, а несвязанная логическая переменная? что работает?
?- replace_at(I,x,[_,_,_,_,_],Ys).
I = 1, Ys = [ x,_B,_C,_D,_E] ;
I = 2, Ys = [_A, x,_C,_D,_E] ;
I = 3, Ys = [_A,_B, x,_D,_E] ;
I = 4, Ys = [_A,_B,_C, x,_E] ;
I = 5, Ys = [_A,_B,_C,_D, x] ;
false.
Да! С монотонным кодом мы получаем логически обоснованные ответы даже с очень общими запросами.