Как вы выполняете поиск и замену списка другим подсписком в Прологе? - PullRequest
5 голосов
/ 29 ноября 2011

Я пытаюсь изменить список с помощью поиска и замены, мне было интересно, как мне выполнить поиск по списку с поисковым термином в виде списка?

Допустим, у меня есть список [1,2,3,4] Я хочу выделить 2 и 3 и заменить их на 5,6, поэтому в идеале у меня мог бы быть предикат:

search_and_replace(Search_Term, Replace_Term, Target_List, Result_List).

eg.

search_and_replace([2,3], [5,6], [1,2,3,4], Result_List), write(Result_List).

Ответы [ 2 ]

6 голосов
/ 29 ноября 2011

Позвольте мне предположить, что вы хотите заменить подпоследовательность в списке другим списком.

Вот общий способ, как это сделать. Вы можете вставить дальнейшие условия в программе.

replacement(A, B,  Ag, Bg) :-
   phrase((seq(S1),seq(A),seq(S2)), Ag),
   phrase((seq(S1),seq(B),seq(S2)), Bg).

seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).

И да, это можно немного оптимизировать - даже его свойство завершения получит прибыль. Но концептуальная ясность - весьма ценная ценность ...

Редактировать: Ваш пример запроса:

?- replacement([2,3], [5,6], [1,2,3,4], Xs).
Xs = [1, 5, 6, 4] ;
false.
4 голосов
/ 29 ноября 2011

Вы можете использовать append / 2 следующим образом:

replace(ToReplace, ToInsert, List, Result) :-
    once(append([Left, ToReplace, Right], List)),
    append([Left, ToInsert, Right], Result).

С или без использования один раз / 1 в зависимости от того, хотите ли вы все возможности или нет.

Чтобы заменить все случаи, я бы выбрал что-то вроде:

replace(ToReplace, ToInsert, List, Result) :-
    replace(ToReplace, ToInsert, List, [], Result).
replace(ToReplace, ToInsert, List, Acc, Result) :-
    append([Left, ToReplace, Right], List),
    append([Acc, Left, ToInsert], NewAcc),
    !,
    replace(ToReplace, ToInsert, Right, NewAcc, Result).
replace(_ToReplace, _ToInsert, [], Acc, Acc).
...