2012-01-14 3 views
1

Я искал учебники о том, какие аккумуляторы и что они делают, однако все объяснения кажутся очень сложными и на самом деле не дают мне достаточно ясного изображения о том, как они работают, чтобы я мог использовать его. Кажется, я понимаю, что аккумуляторы держат что-то вроде числа, которое затем может быть вызвано другими фрагментами кода и изменено. Проблема в том, что, хотя я понимаю, что такое аккумулятор и знаю, когда он мне нужен, я не слишком уверен, как его использовать.Пролог Что такое Аккумуляторы и функция + member

Я имею в виду из обучающих программ, которые я видел, иногда, как кажется, аккумулятор представляет собой пустой список, в то время как другие времена, похоже, «0» оставляют меня недоумением, что именно можно считать аккумулятором, а что нет. Может кто-нибудь, пожалуйста, объясните мне простыми словами, как именно аккумулятор можно использовать?

Также во второй части моего вопроса, я, кажется, заметил людей, использующих эту массу в своих Prolog кодов:

\+member 

я сумел сделать вывод, что у него есть что-то делать со списками, так как Я всегда вижу, что он используется внутри строки кода, которая делает что-то в списке, однако после поиска я обнаружил, что то, что на самом деле означает +, означает «Отрицание как отказ - не доказуемо», хотя я действительно не понимаю, что это означает или даже если этот человек был прав. Опять же, может кто-нибудь, пожалуйста, объясните мне, что именно делает + член и что его можно использовать, пытаясь упростить ваше объяснение, большие слова путают меня xD.

Большое спасибо за любую помощь по этим двум вопросам.

ответ

8

Во-первых, \+ является отрицанием цели. Это удается, когда цель, следующая за ней, терпит неудачу. Например:

?- member(3, [1,2,3]). # 3 is a member of the List 
true. 

?- member(4, [1,2,3]). # 4 is not a member 
false. 

?- \+member(4, [1,2,3]). # succeeds, because 'member' fails 
true. 

?- \+member(3, [1,2,3]). 
false. 

?- atom_chars('hi', C). 
C = [h, i]. 

?- atom_chars('hi', [h, i]). 
true. 

?- atom_chars('hello', [h, i]). 
false. 

?- \+atom_chars('hello', [h, i]). 
true. 

Во-вторых, аккумулятор способ заправки состояния через рекурсию, чтобы воспользоваться преимуществами оптимизации хвостовой рекурсии.

Рассмотрим эти два эквивалентных способа вычисления факториала:

?- [user]. 
|: fact_simple(0, 1). 
|: fact_simple(N, F) :- 
     N1 is N-1, 
     fact_simple(N1, F1), 
     F is N*F1. 
|: % user://2 compiled 0.00 sec, 440 bytes 
true. 

?- fact_simple(6, F). 
F = 720 . 

[user]. 
|: fact_acc(N, F) :- fact_acc(N, 1, F). 
|: fact_acc(0, Acc, Acc). 
|: fact_acc(N, Acc0, F) :- 
     N1 is N-1, 
     Acc is Acc0 * N, 
     fact_acc(N1, Acc, F). 
|: % user://4 compiled 0.00 sec, 1,912 bytes 
true. 

?- fact_acc(6, F). 
F = 720 . 

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

В второй версии вместо этого используется аккумулятор (Acc). Обратите внимание, что 1 не является аккумулятором, но это начальное значение. После этого каждый вызов предиката умножает значение N -значение с аккумулятором и по мере того, как рекурсия достигает базового флага, значение аккумулятора уже является окончательным значением.

Вопрос на самом деле не является «чем может быть аккумулятор? (0 или пустой список или что-то еще). Это всего лишь способ накопления ценностей «когда вы идете» и никогда не возвращаетесь к вызывающему предикату. Таким образом, система Prolog не должна создавать постоянно растущий стек вызовов.

Обратите внимание, однако, что в этом примере порядок умножений естественным образом отменяется. Для умножения это не имеет значения, но для других значений (например, списков) нужно позаботиться об этом.

fact_simple умножился как 1 * 2 * 3 * 4 * 5 * 6, а fact_acc имел его как 1 * 6 * 5 * 4 * 3 * 2. Если это неясно, просто сделайте следы обоих!

+0

Спасибо, это помогло тонны – Arun22

+1

Добро пожаловать. Я просто хотел бы добавить, что «шаблон» аккумулятора не является специфическим прологом, а скорее элементом функционального программирования. – firefrorefiddle