Мета-предикаты Пролога: применение предиката к спискам, передача константы - PullRequest
2 голосов
/ 22 сентября 2011

Предположим, что вы хотите предикат, который заменяет Number1 на Number2 в списке.
Конечно, написать рекурсивную функцию для этого тривиально, например:

replace(_,_,[],[]).
replace(N1,N2,[N1|T], [N2|NT]):-
    replace(N1,N2,T,NT).
replace(N1,N2,[H|T],[H|NT]):-
    replace(N1,N2,T,NT).

У меня вопрос, есть ли способ сделать это с помощью maplist / x (или аналогичных мета-предикатов).
Для этого можно использовать глобальные переменные, например:

replace(N1,N2,L1,L2):-
    nb_setval(numbers,[N1,N2]),
    maplist(replace_in,L1,L2).

replace_in(N1,N2):-
    nb_getval(numbers,[N1,N2]).
    replace_in(X,X).

Другая идея состоит в том, чтобы создать список с одинаковыми номерами List_of_N1 и List_of_N2 и передать их в maplist / 4.
Никто из них не выглядит привлекательным для меня, есть идеи?

Ответы [ 2 ]

4 голосов
/ 22 сентября 2011

В качестве отступления: при заданном вами определении рассмотрим, например, непредвиденное второе решение в:

?- replace(1, 4, [1,2,3], Ls).
Ls = [4, 2, 3] ;
Ls = [1, 2, 3] ;
false.

Что касается самого вопроса, рассмотрим:

replace(A, B, X, Y) :- ( X == A -> Y = B ; Y = X ).

Пример запроса:

?- maplist(replace(1,4), [1,2,3], Ls).
Ls = [4, 2, 3].


Для , я рекомендую действительно реляционную версию, которая может использоваться во всех направлениях:

replacement(A, B, A, B).
replacement(A, _, X, X) :- dif(A, X).

Пример:

?- maplist(replacement(a,b), [X], Rs).
Rs = [b],
X = a ;
Rs = [X],
dif(X, a).
1 голос
/ 22 сентября 2011

Как насчет этого:

replace(N1,N2,L1,L2):-
    maplist(replace_in,[N1-N2-T|T], L1,L2).

replace_in(N1-N2-T, X, Y):-
  (X=N1 -> Y=N2 ; Y=X),
  (T=[N1-N2-L|L] ; T=[]).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...