2015-10-22 2 views
1

Я пытаюсь изучить Prolog. У меня проблема и решение для этого в Prolog. Хотя я не могу полностью понять код.Каково объяснение этого кода?

Проблема заключается в том -

Write a procedure mydelete(X, HasXs, OneLessXs) that returns 

%  ?- mydelete(2, [1,2,3,4], L) . --> L = [1,3,4] 

%  ?- mydelete(2, [1,2,3,2], L) . --> L = [1,3,2] ; L = [1,2,3] 

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

У меня есть решение, но я точно не знаю, как этот код работает.

mydelete(X,[X|T],T). 
mydelete(X,[H|T1],[H|T2]) :- mydelete(X,T1,T2). 

По моему разумению, первая строка отображает L = ..., когда он находит соответствие с X в голове списка.

Во второй строке кода он просто выталкивает голову из списка ввода и отправляет этот обновленный список рекурсивно.

Но, здесь, мы не определили T2.

Рассмотрим пример этого.

mydelete(2, [1,2,3,4], L) . --> this is the call. 

Х = 2, список = [1,2,3,4], поэтому, Н = 1, Т = [2,3,4].

Таким образом, он не выполняет строку 1 кода. Теперь речь идет о второй строке кода.

mydelete(X,[H|T1],[H|T2]) :- mydelete(X,T1,T2). 

Здесь также Х = 2, Н = 1, Т1 = [2,3,4], Т2 =.

Таким образом, на следующей рекурсии,

Х = 2, список = [2,3,4], Н соответствует Х, таким образом, линия 1 будут выполнены.

Следовательно, X = 2, Т = [3,4]

Так, он должен напечатать = [3,4]. (я знаю, [1,3,4] - правильный ответ. Я не могу понять объяснения этого кода)

Мой вопрос: что не так в моем понимании?

И, что использование [H | T2] в

mydelete(X,[H|T1],[H|T2]) :- mydelete(X,T1,T2). 

Спасибо! Пожалуйста, помогите мне!

Редактировать: Я попытался удалить H из [H | T2]. Это печать [3,4]. Как H добавляет 1 в качестве префикса в список [3,4]?

+1

Учитывая описание проблемы, я бы вообще не использовал 'write', а просто« L »объединял правильный ответ. – aschepler

+0

Прошу прощения, я скопировал код здесь немного неправильно. Я меняю его. Извините за беспокойство. Я пытался что-то само собой. и я приклеил его здесь по ошибке. Еще раз извините! :( –

+0

удален write(). –

ответ

1

Лучший способ подумать об этом как о императивном программисте состоит в том, что последний аргумент является видом возвращаемого значения.Вы видите, что первый звонок, который вы делаете «возвращает» [H|T2], а не только T2, так выглядит первый элемент списка: после рекурсии для вычисления значения T2 mydelete добавляет H (что в этом случае равно 1) к началу возвращаемого списка.

+0

Я думаю, что могу понять, что вы пытаетесь сказать. Позвольте мне объяснить это один раз и, пожалуйста, также сообщите мне, если я ошибаюсь. Строка 2, которая является mydelete (X, [H | T1], [H | T2 ]): - mydelete (X, T1, T2) инициирует рекурсию и каждый раз отбрасывает головку списка. Таким образом, когда строка 1 возвращает [3,4], строка 2 добавляет к ней префикс (H), когда управление приходит к предыдущему шагу. Правильно ли я понял? –

+0

Это очень правильно. – tobyodavies

0

Что такое [H|T2]?

В своих объяснениях, вы забыли учесть, что третий аргумент, L, в настоящее время объединены с [H|T2]. До этого момента L был бесплатным (в вашем случае), и теперь вы знаете, что это список, начинающийся с H. Остальная часть списка T2 теперь является третьим аргументом для рекурсивного вызова и будет унифицирована аналогично, пока вы не достигнете базового аргумента.

Кстати, что происходит, когда ваш список пуст?