удалить элемент из списка - PullRequest
0 голосов
/ 27 ноября 2011
del(X,[X|Reszta],Reszta).
del(X,[Y|Ogon],[Y|Reszta]) :- del(X,Ogon,Reszta).

Я не понимаю этот код.Если я спрошу:

?- del(c, [a,b,c],X).

Компилятор перейдет на вторую строку и запустит рекурсивный цикл del(x,[b,c],[]).Я прав?

Ответы [ 2 ]

1 голос
/ 27 ноября 2011

используйте trace / 0, чтобы увидеть, что произойдет.в этом случае:

    4 ?- trace.
true.

[trace] 4 ?- del(c,[a,b,c],X).
   Call: (6) del(c, [a, b, c], _G531) ? creep
   Call: (7) del(c, [b, c], _G607) ? creep
   Call: (8) del(c, [c], _G610) ? creep
   Exit: (8) del(c, [c], []) ? creep
   Exit: (7) del(c, [b, c], [b]) ? creep
   Exit: (6) del(c, [a, b, c], [a, b]) ? creep
X = [a, b] .

на каждом прологе «поворота» будет проверять, является ли первый элемент тем, который мы хотим удалить.если это так, мы сделали.в противном случае мы сохраняем голову и рекурсивно вызываем del / 3 для конца списка

, следует ли нам думать о том, что произойдет, если элемент отсутствует в данном списке, это другой вопрос;мы можем захотеть, чтобы предикат потерпел неудачу в этом случае, мы могли бы хотеть вернуть весь список, а затем мы должны добавить del(_, [], [])., как сказал мог

1 голос
/ 27 ноября 2011

Вы можете увидеть, как работает интерпретатор, набрав (ну, по крайней мере, в swi-pl, должно быть что-то похожее в других реализациях):

?- trace, del(c, [a,b,c],X).

Кстати, вы, конечно, забыли включить строку, такую ​​как:

del(_, [], []).

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

По сути, здесь все будет работать так:
del (c, [a, b, c], X) => c не может быть объединен с a, поэтому мы будем включать его при построении списка с конца.
del (c, [b, c], X) => c нельзя объединить с b, поэтому мы будем включать b при построении списка с конца.
del (c, [c], X) => c можно объединить с c, поэтому мы не будем включать c при построении списка с конца.
del (c, [], X) => [] истинно, когда X = [], поэтому, скажем, X = [], и теперь давайте построим наш список результатов, взбираясь по рекурсии:
X = [] при подъеме на один шаг вверх, потому что c не включен.
X = [b] при подъеме на один шаг вверх, потому что b включено.
X = [a, b] при подъеме на одну ступеньку, потому что включен a.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...