Рекурсия Пролога в сумме n натуральных чисел

Мне трудно понять, как значение Z постоянно меняется. Конкретный шаг указан в выходных данных трассировки стека.

Вот код, который я использую для нахождения суммы N натуральных чисел:

sum1(1,1).
sum1(N, Sum) :-
   Next is N-1,
   sum1(Next, Z),
   Sum is Z + N.

Вот трассировка стека -

?- sum1(3,_).
   Call: (8) sum1(3, _2668) ? creep
   Call: (9) _2860 is 3+ -1 ? creep
   Exit: (9) 2 is 3+ -1 ? creep
   Call: (9) sum1(2, _2862) ? creep
   Call: (10) _2866 is 2+ -1 ? creep
   Exit: (10) 1 is 2+ -1 ? creep
   Call: (10) sum1(1, _2868) ? creep
   Exit: (10) sum1(1, 1) ? creep
   Call: (10) _2872 is 1+2 ? creep
   Exit: (10) 3 is 1+2 ? creep
   Exit: (9) sum1(2, 3) ? creep **%How is Z assigned value 3 ?**
   Call: (9) _2668 is 3+3 ? creep
    Exit: (9) 6 is 3+3 ? EOF: exit

Заранее спасибо!


person Markandeya    schedule 09.04.2018    source источник
comment
По сути, переменные привязаны к вызову, в котором они находятся. Любым переменным между вызовами назначаются новые анонимные переменные, пока они не будут объединены с тем, что им передается. Это означает, что если вы используете Z в нескольких местах, Z не конкретизируется, и, скажем, Z = A, создается новая анонимная переменная _1234, назначенная как для A, так и для всех местоположений, где используется Z.   -  person G_V    schedule 10.04.2018


Ответы (1)


Это не «изменение»; каждое доказательство sum1 получает свои версии N, Sum, Next и Z. Вот почему в трассировке стека каждый из них получает свое сгенерированное имя (например, _2860), поэтому Пролог может отличить их друг от друга.

Что касается вашего конкретного вопроса, на 2 строки выше строки, о которой вы спрашиваете, этот конкретный Sum - это _2872; поэтому для доказательства _2872 is 1+2 требуется, чтобы _2872 было 3. И этот Sum соответствует предыдущему вызову sum(1, _2868), где _2868 был Z sum1 (как вы можете видеть из двух строк выше).

person Scott Hunter    schedule 09.04.2018
comment
Итак, 3 присваивается sum1(2, _2862), потому что пролог соответствует предыдущему вызову. - person Markandeya; 09.04.2018
comment
3 назначается _2862. - person Scott Hunter; 09.04.2018