Элемент пролога в замене списков - PullRequest
6 голосов
/ 01 мая 2011

Привет, мне было интересно, не могли бы вы помочь мне с этим

Из программирования на Прологе: напишите сценарий Пролога для замены любого данного элемента в списках другим заданным элементом.Например:

replace( 3, a,[1,2,3,4,3,5], [1,2,a,4,a,5])=true

Большое спасибо заранее

Ответы [ 5 ]

12 голосов
/ 02 мая 2011

В Прологе большая часть обработки списка выполняется обработкой заголовка, а затем рекурсивной обработкой остальной части списка. Конечно, вы не можете забыть о базовом случае, который является пустым списком.

Замена чего-либо чем-либо в пустом списке снова приводит к пустому списку. Если заголовок списка совпадает с элементом для замены, замените его, в противном случае оставьте его как есть. В обоих случаях обработайте рекурсивно остальную часть списка. Перевод с английского на пролог:

replace(_, _, [], []).
replace(O, R, [O|T], [R|T2]) :- replace(O, R, T, T2).
replace(O, R, [H|T], [H|T2]) :- H \= O, replace(O, R, T, T2).
6 голосов
/ 03 мая 2015

Все реализации , представленные до сих пор в других ответах, логически несостоятельны при использовании с неосновными терминами. Рассмотрим оригинальный запрос и небольшой вариант:

?- replace(3,three,[1,2,3],Xs).
Xs = [1,2,three] ;                 % OK: correct
false

?- A=3, replace(A,B,[1,2,3],Xs).   % OK: correct
Xs = [1,2,B], A = 3 ;
false

Это работает! Давайте зададим несколько очень похожих запросов:

?- replace(A,B,[1,2,3],Xs).        % FAIL: should succeed more than once...
Xs = [B,2,3], A = 1 ;              %       ... but the other solutions are missing 
false

?- replace(A,B,[1,2,3],Xs), A=3.   % FAIL: this query _should_ succeed ...
false                              %       ... it does not!

Что происходит? Положите вину на мета-логических встроенных (!)/0 и (\=)/2, которые очень сложны в использовании правильно и часто делает код хрупким, нечистым и логически необоснованным.

Для сохранения логической обоснованности , придерживайтесь логической чистоты и воздержитесь от мета-логических «особенностей», когда это возможно! К счастью, большинство реализаций Пролога поддерживают dif/2 как логическую альтернативу (\=)/2. Давайте использовать это:

% code by @svick, modified to use dif/2 instead of (\=)/2
replaceP(_, _, [], []).
replaceP(O, R, [O|T], [R|T2]) :- replaceP(O, R, T, T2).
replaceP(O, R, [H|T], [H|T2]) :- dif(H,O), replaceP(O, R, T, T2).

Давайте снова запустим вышеуказанные запросы, на этот раз с улучшенным replaceP/4:

?- replaceP(3,three,[1,2,3],Xs).
Xs = [1,2,three] ;                 % OK: correct, like before
false

?- replaceP(A,B,[1,2,3],Xs).       % OK: four solutions, not just one
Xs = [B,2,3], A = 1 ;         
Xs = [1,B,3], A = 2 ;
Xs = [1,2,B], A = 3 ;
Xs = [1,2,3], dif(A,1),dif(A,2),dif(A,3) ;
false

?- replaceP(A,B,[1,2,3],Xs), A=3.  % OK (succeeds now)
Xs = [1,2,B], A = 3 ;                 
false
?- A=3, replaceP(A,B,[1,2,3],Xs).  % OK (same as before)
Xs = [1,2,B], A = 3 ;
false
0 голосов
/ 02 марта 2014
domains
I=integer*
K=integer*
Z=integer
A=integer
predicates
nondeterm  rep(I,Z,A,K)
clauses
rep([],_,_,[]).
rep([Z|T1],Z,A,[A|T2]):- rep(T1,Z,A,T2).
rep([H|T1],Z,A,[H|T2]) :- rep(T1,Z,A,T2).
goal
rep([1,2,3],2,4,X).
0 голосов
/ 01 июня 2011
replace(E,S,[],[]).
replace(E,S,[E|T1],[S|T2]):-replace(E,S,T1,T2).
replace(E,S,[H|T1],[H|T2]):-E\=H, replace(E,S,T1,T2).

Идея проста: если элементы совпадают, измените его, если нет, идите вперед до пустого.

0 голосов
/ 02 мая 2011
replace(_, _ , [], []).

replace(X, Y, [ X | Z ], [ Y | ZZ]):- ! , replace( X, Y, Z, ZZ).

replace(X, Y, [ W | Z], [ W | ZZ] :- replace(X, Y, Z, ZZ). 

Хотя обычно 3-ий арг был бы первым. И, строго говоря, выше ничего не заменяет в списке, это просто ответ, если 4-й аргумент похож на 3-й аргумент, но с Y 'вместо X'.

...